touched up pf_method_get_source_file() and pf_method_get_ip_source_line()

This commit is contained in:
hyunghwan.chung 2019-07-11 15:58:16 +00:00
parent d5475d79b6
commit fcf6d3ffc1
6 changed files with 146 additions and 38 deletions

View File

@ -322,7 +322,7 @@ class(#pointer) CompiledMethod(Object)
ntmprs,
nargs,
//code, <-- only if moo is built with MOO_USE_METHOD_TRAILER disable.
source_text,
dbi_text_offset,
dbi_file_offset,
source_line,
dbi_method_offset.
@ -348,6 +348,7 @@ class(#pointer) CompiledMethod(Object)
^self.name
}
method(#primitive) sourceText.
method(#primitive) sourceFile.
method(#primitive) ipSourceLine: ip.

View File

@ -84,8 +84,10 @@ int moo_initdbgi (moo_t* moo, moo_oow_t capa)
tmp->_capa = capa;
tmp->_len = MOO_SIZEOF(*tmp);
/* tmp->_last_file = 0;
tmp->_last_class = 0;
tmp->_last_file = 0;
tmp->_last_text = 0;
tmp->_last_method = 0; */
moo->dbgi = tmp;
return 0;
@ -155,7 +157,7 @@ int moo_addfiletodbgi (moo_t* moo, const moo_ooch_t* file_name, moo_oow_t* start
di = (moo_dbgi_file_t*)secure_dbgi_space(moo, req_bytes);
if (!di) return -1;
di->_type = MOO_DBGINFO_MAKE_TYPE(MOO_DBGINFO_TYPE_CODE_FILE, 0);
di->_type = MOO_DBGI_MAKE_TYPE(MOO_DBGI_TYPE_CODE_FILE, 0);
di->_len = req_bytes;
di->_next = moo->dbgi->_last_file;
moo_copy_oocstr ((moo_ooch_t*)(di + 1), name_len + 1, file_name);
@ -167,6 +169,39 @@ int moo_addfiletodbgi (moo_t* moo, const moo_ooch_t* file_name, moo_oow_t* start
return 0;
}
int moo_addtexttodbgi (moo_t* moo, const moo_ooch_t* text_ptr, moo_oow_t text_len, moo_oow_t* start_offset)
{
moo_oow_t text_bytes, text_bytes_aligned, req_bytes;
moo_dbgi_text_t* di;
if (!moo->dbgi)
{
if (start_offset) *start_offset = MOO_NULL;
return 0; /* debug information is disabled*/
}
/* NOTE: there is no duplication check for text */
text_bytes = (text_len + 1) * MOO_SIZEOF(*text_ptr);
text_bytes_aligned = MOO_ALIGN_POW2(text_bytes, MOO_SIZEOF_OOW_T);
req_bytes = MOO_SIZEOF(moo_dbgi_text_t) + text_bytes_aligned;
di = (moo_dbgi_text_t*)secure_dbgi_space(moo, req_bytes);
if (!di) return -1;
di->_type = MOO_DBGI_MAKE_TYPE(MOO_DBGI_TYPE_CODE_TEXT, 0);
di->_len = req_bytes;
di->_next = moo->dbgi->_last_text;
di->text_len = text_len;
moo_copy_oochars ((moo_ooch_t*)(di + 1), text_ptr, text_len);
moo->dbgi->_last_text = moo->dbgi->_len;
moo->dbgi->_len += req_bytes;
if (start_offset) *start_offset = moo->dbgi->_last_text;
return 0;
}
int moo_addclasstodbgi (moo_t* moo, const moo_ooch_t* class_name, moo_oow_t file_offset, moo_oow_t file_line, moo_oow_t* start_offset)
{
moo_oow_t name_len, name_bytes, name_bytes_aligned, req_bytes;
@ -199,7 +234,7 @@ int moo_addclasstodbgi (moo_t* moo, const moo_ooch_t* class_name, moo_oow_t file
di = (moo_dbgi_class_t*)secure_dbgi_space(moo, req_bytes);
if (!di) return -1;
di->_type = MOO_DBGINFO_MAKE_TYPE(MOO_DBGINFO_TYPE_CODE_CLASS, 0);
di->_type = MOO_DBGI_MAKE_TYPE(MOO_DBGI_TYPE_CODE_CLASS, 0);
di->_len = req_bytes;
di->_next = moo->dbgi->_last_class;
di->_file = file_offset;
@ -230,7 +265,7 @@ int moo_addmethodtodbgi (moo_t* moo, moo_oow_t file_offset, moo_oow_t class_offs
di = (moo_dbgi_method_t*)secure_dbgi_space(moo, req_bytes);
if (!di) return -1;
di->_type = MOO_DBGINFO_MAKE_TYPE(MOO_DBGINFO_TYPE_CODE_METHOD, 0);
di->_type = MOO_DBGI_MAKE_TYPE(MOO_DBGI_TYPE_CODE_METHOD, 0);
di->_len = req_bytes;
di->_next = moo->dbgi->_last_method;
di->_file = file_offset;

View File

@ -2216,10 +2216,10 @@ static moo_pfrc_t pf_context_find_exception_handler (moo_t* moo, moo_mod_t* mod,
}
/* ------------------------------------------------------------------ */
static moo_pfrc_t pf_method_get_source_file (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
static moo_pfrc_t pf_method_get_source_text (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{
moo_oop_method_t rcv;
moo_oop_t retv = moo->_nil;
moo_oop_t retv = moo->_nil; /* TODO: empty string instead of nil? */
/* TODO: return something else lighter-weight than a string? */
rcv = (moo_oop_method_t)MOO_STACK_GETRCV(moo, nargs);
@ -2227,19 +2227,65 @@ static moo_pfrc_t pf_method_get_source_file (moo_t* moo, moo_mod_t* mod, moo_ooi
if (moo->dbgi)
{
if (MOO_OOP_IS_SMOOI(rcv->dbi_file_offset) && MOO_OOP_TO_SMOOI(rcv->dbi_file_offset) > 0)
if (MOO_OOP_IS_SMOOI(rcv->dbi_text_offset))
{
moo_dbgi_file_t* di;
const moo_ooch_t* file_name;
moo_ooi_t dbi_text_offset;
di = (moo_dbgi_file_t*)&((moo_uint8_t*)moo->dbgi)[MOO_OOP_TO_SMOOI(rcv->dbi_file_offset)];
/* TODO: check if di is the file type... otherwise, it's internal corruption */
dbi_text_offset = MOO_OOP_TO_SMOOI(rcv->dbi_text_offset);
if (dbi_text_offset > 0)
{
moo_dbgi_text_t* di;
const moo_ooch_t* text_ptr;
file_name = (const moo_ooch_t*)(di + 1);
moo_pushvolat (moo, &retv);
retv = moo_makestring(moo, file_name, moo_count_oocstr(file_name));
moo_popvolat (moo);
if (!retv) return MOO_PF_FAILURE;
MOO_ASSERT (moo, dbi_text_offset < moo->dbgi->_len);
di = (moo_dbgi_text_t*)&((moo_uint8_t*)moo->dbgi)[dbi_text_offset];
MOO_ASSERT (moo, MOO_DBGI_GET_TYPE_CODE(di->_type) == MOO_DBGI_TYPE_CODE_TEXT);
text_ptr = (const moo_ooch_t*)(di + 1);
moo_pushvolat (moo, &retv);
retv = moo_makestring(moo, text_ptr, di->text_len);
moo_popvolat (moo);
if (!retv) return MOO_PF_FAILURE;
}
}
}
MOO_STACK_SETRET (moo, nargs, retv);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_method_get_source_file (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{
moo_oop_method_t rcv;
moo_oop_t retv = moo->_nil; /* TODO: empty string instead of nil? */
/* TODO: return something else lighter-weight than a string? */
rcv = (moo_oop_method_t)MOO_STACK_GETRCV(moo, nargs);
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo, rcv) == moo->_method);
if (moo->dbgi)
{
if (MOO_OOP_IS_SMOOI(rcv->dbi_file_offset))
{
moo_ooi_t dbi_file_offset;
dbi_file_offset = MOO_OOP_TO_SMOOI(rcv->dbi_file_offset);
if (dbi_file_offset > 0)
{
moo_dbgi_file_t* di;
const moo_ooch_t* file_name;
MOO_ASSERT (moo, dbi_file_offset < moo->dbgi->_len);
di = (moo_dbgi_file_t*)&((moo_uint8_t*)moo->dbgi)[dbi_file_offset];
MOO_ASSERT (moo, MOO_DBGI_GET_TYPE_CODE(di->_type) == MOO_DBGI_TYPE_CODE_FILE);
file_name = (const moo_ooch_t*)(di + 1);
moo_pushvolat (moo, &retv);
retv = moo_makestring(moo, file_name, moo_count_oocstr(file_name));
moo_popvolat (moo);
if (!retv) return MOO_PF_FAILURE;
}
}
}
@ -2269,18 +2315,24 @@ static moo_pfrc_t pf_method_get_ip_source_line (moo_t* moo, moo_mod_t* mod, moo_
if (source_line >= 0 && ipv >= 0 && MOO_OOP_IS_SMOOI(rcv->dbi_method_offset))
{
moo_dbgi_method_t* di;
moo_ooi_t dbi_method_offset;
moo_oow_t* code_loc_ptr;
dbi_method_offset = MOO_OOP_TO_SMOOI(rcv->dbi_method_offset);
di = (moo_dbgi_method_t*)&((moo_uint8_t*)moo->dbgi)[dbi_method_offset];
code_loc_ptr = (moo_oow_t*)((moo_uint8_t*)(di + 1) + di->code_loc_start);
if (ipv < di->code_loc_len && code_loc_ptr[ipv] <= MOO_SMOOI_MAX)
if (dbi_method_offset > 0)
{
line = code_loc_ptr[ipv] + source_line; /* this won't overflow but can exceed MOO_SMOOI_MAX */
if (line > MOO_SMOOI_MAX) line = 0;
moo_dbgi_method_t* di;
moo_oow_t* code_loc_ptr;
MOO_ASSERT (moo, dbi_method_offset < moo->dbgi->_len);
di = (moo_dbgi_method_t*)&((moo_uint8_t*)moo->dbgi)[dbi_method_offset];
MOO_ASSERT (moo, MOO_DBGI_GET_TYPE_CODE(di->_type) == MOO_DBGI_TYPE_CODE_METHOD);
code_loc_ptr = (moo_oow_t*)((moo_uint8_t*)(di + 1) + di->code_loc_start);
if (ipv < di->code_loc_len && code_loc_ptr[ipv] <= MOO_SMOOI_MAX)
{
line = code_loc_ptr[ipv] + source_line; /* this won't overflow but can exceed MOO_SMOOI_MAX */
if (line > MOO_SMOOI_MAX) line = 0;
}
}
}
/* TODO: security check for data corruption? check if the ipv offset and the size calcualted doesn't exceed di->_len... */
@ -4015,6 +4067,7 @@ static pf_t pftab[] =
{ "CompiledMethod_ipSourceLine:", { pf_method_get_ip_source_line, 1, 1 } },
{ "CompiledMethod_sourceFile", { pf_method_get_source_file, 0, 0 } },
{ "CompiledMethod_sourceText", { pf_method_get_source_text, 0, 0 } },
{ "Error_asCharacter", { pf_error_as_character, 0, 0 } },
{ "Error_asInteger", { pf_error_as_integer, 0, 0 } },

View File

@ -1670,10 +1670,10 @@ void moo_dumpsymtab (moo_t* moo);
void moo_dumpdic (moo_t* moo, moo_oop_dic_t dic, const moo_bch_t* title);
int moo_addfiletodbgi (moo_t* moo, const moo_ooch_t* file_name, moo_oow_t* start_offset);
int moo_addtexttodbgi (moo_t* moo, const moo_ooch_t* text_ptr, moo_oow_t text_len, moo_oow_t* start_offset);
int moo_addclasstodbgi (moo_t* moo, const moo_ooch_t* class_name, moo_oow_t file_offset, moo_oow_t file_line, moo_oow_t* start_offset);
int moo_addmethodtodbgi (moo_t* moo, moo_oow_t file_offset, moo_oow_t class_offset, const moo_ooch_t* method_name, const moo_oow_t* code_loc_ptr, moo_oow_t code_loc_len, moo_oow_t* start_offset);
/* ========================================================================= */
/* comp.c */
/* ========================================================================= */

View File

@ -585,7 +585,7 @@ struct moo_method_t
moo_oop_byte_t code; /* ByteArray */
#endif
moo_oop_t source_text; /* source text. String if available. nil if not */
moo_oop_t dbi_text_offset; /* SmallInteger. Offset to source text in moo->dbgi. 0 if unavailable */
moo_oop_t dbi_file_offset; /* SmallInteger. source file path that contains the definition of this method. offset from moo->dbgi. 0 if unavailable */
moo_oop_t source_line; /* SmallInteger. line of the source file where the method definition begins. valid only if dbi_file_offset is greater than 0 */
moo_oop_t dbi_method_offset; /* SmallInteger */
@ -952,6 +952,7 @@ struct moo_dbgi_t
moo_oow_t _len;
moo_oow_t _last_file; /* offset to the last file element added */
moo_oow_t _last_class; /* offset to the last class element added */
moo_oow_t _last_text; /* offset to the last text element added */
moo_oow_t _last_method;
/* actual information is recorded here */
};
@ -959,17 +960,20 @@ struct moo_dbgi_t
enum moo_dbgi_type_t
{
/* bit 8 to bit 15 */
MOO_DBGINFO_TYPE_CODE_FILE = 0,
MOO_DBGINFO_TYPE_CODE_CLASS = 1,
MOO_DBGI_TYPE_CODE_FILE = 0,
MOO_DBGI_TYPE_CODE_CLASS = 1,
MOO_DBGI_TYPE_CODE_TEXT = 2,
/* TODO: interface? etc? */
MOO_DBGINFO_TYPE_CODE_METHOD = 2,
MOO_DBGI_TYPE_CODE_METHOD = 3, /* method instruction location information */
/* low 8 bits */
MOO_DBGINFO_TYPE_FLAG_INVALID = (1 << 0)
MOO_DBGI_TYPE_FLAG_INVALID = (1 << 0)
};
typedef enum moo_dbgi_type_t moo_dbgi_type_t;
#define MOO_DBGINFO_MAKE_TYPE(code,flags) (((code) << 8) | (flags))
#define MOO_DBGI_MAKE_TYPE(code,flags) (((code) << 8) | (flags))
#define MOO_DBGI_GET_TYPE_CODE(type) ((type) >> 8)
#define MOO_DBGI_GET_TYPE_FLAGS(type) ((type) & 0xFF)
typedef struct moo_dbgi_file_t moo_dbgi_file_t;
struct moo_dbgi_file_t
@ -980,6 +984,22 @@ struct moo_dbgi_file_t
/* ... file path here ... */
};
typedef struct moo_dbgi_text_t moo_dbgi_text_t;
struct moo_dbgi_text_t
{
moo_oow_t _type;
moo_oow_t _len; /* length of this record including the header and the text payload */
moo_oow_t _next; /* offset to a previous text */
/*moo_oow_t _file;
moo_oow_t _line; */
moo_oow_t text_len;
/*moo_oow_t class_name_start; <--- needed for compaction.
moo_oow_t method_name_start; <--- needed for compaction */
/* ... text ... */
/* class name... */
/* method name ... */
};
typedef struct moo_dbgi_class_t moo_dbgi_class_t;
struct moo_dbgi_class_t
{
@ -1005,6 +1025,8 @@ struct moo_dbgi_method_t
/* ... code line numbers here ... */
};
/* =========================================================================
* VM LOGGING
* ========================================================================= */

View File

@ -2013,6 +2013,7 @@ static int vm_startup (moo_t* moo)
#elif defined(USE_EPOLL)
#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
xtn->ep = epoll_create1(EPOLL_CLOEXEC);
if (xtn->ep == -1) xtn->ep = epoll_create(1024);
#else
xtn->ep = epoll_create(1024);
#endif
@ -2023,13 +2024,9 @@ static int vm_startup (moo_t* moo)
goto oops;
}
#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
/* do nothing */
#else
#if defined(FD_CLOEXEC)
flag = fcntl(xtn->ep, F_GETFD);
if (flag >= 0) fcntl (xtn->ep, F_SETFD, flag | FD_CLOEXEC);
#endif
if (flag >= 0 && !(flag & FD_CLOEXEC)) fcntl (xtn->ep, F_SETFD, flag | FD_CLOEXEC);
#endif
#elif defined(USE_POLL)
@ -3232,7 +3229,7 @@ static LONG WINAPI msw_exception_filter (struct _EXCEPTION_POINTERS* exinfo)
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, exinfo->ExceptionRecord->ExceptionAddress, &mod);
//GetModuleInformation (GetCurrentProcess(), mod, &modinfo, MOO_SIZEOF(modinfo));
/*GetModuleInformation (GetCurrentProcess(), mod, &modinfo, MOO_SIZEOF(modinfo));*/
GetModuleFileNameExW (GetCurrentProcess(), mod, expath, MOO_SIZEOF(expath));
#else
GetModuleFileNameW (MOO_NULL, expath, MOO_SIZEOF(expath));