From fcf6d3ffc1c2eae70ce389fcfbb310c7b764771c Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Thu, 11 Jul 2019 15:58:16 +0000 Subject: [PATCH] touched up pf_method_get_source_file() and pf_method_get_ip_source_line() --- moo/kernel/Context.moo | 3 +- moo/lib/debug.c | 43 +++++++++++++++++-- moo/lib/exec.c | 93 +++++++++++++++++++++++++++++++++--------- moo/lib/moo-prv.h | 2 +- moo/lib/moo.h | 34 ++++++++++++--- moo/lib/std.c | 9 ++-- 6 files changed, 146 insertions(+), 38 deletions(-) diff --git a/moo/kernel/Context.moo b/moo/kernel/Context.moo index 06a0c49..e05afdb 100644 --- a/moo/kernel/Context.moo +++ b/moo/kernel/Context.moo @@ -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. diff --git a/moo/lib/debug.c b/moo/lib/debug.c index e304ea9..a0d8187 100644 --- a/moo/lib/debug.c +++ b/moo/lib/debug.c @@ -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; diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 1ac8ce9..c49affa 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -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 } }, diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 91ae0a4..012d776 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -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 */ /* ========================================================================= */ diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 1acf862..f703b57 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -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 * ========================================================================= */ diff --git a/moo/lib/std.c b/moo/lib/std.c index ae89808..626d516 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -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));