From b3088901e18927c1218ea1691b4402fa9bc3a0fb Mon Sep 17 00:00:00 2001 From: Anthony Drendel Date: Sat, 20 Feb 2021 23:09:14 +0100 Subject: [PATCH] Support exported functions with the same name (#199) * Support exported functions with the same name * Fix error for shadowing local variable * Replace function->name with GetFunctionName() * Replace another direct i-var access of func->name --- platforms/python/m3module.c | 2 +- source/m3_compile.c | 2 +- source/m3_config.h | 4 ++++ source/m3_env.c | 42 ++++++++++++++++++++++++++++++------- source/m3_env.h | 8 ++++--- source/m3_exec.h | 8 +++---- source/m3_info.c | 3 ++- source/m3_module.c | 5 +++-- source/m3_parse.c | 11 ++++++---- 9 files changed, 61 insertions(+), 24 deletions(-) diff --git a/platforms/python/m3module.c b/platforms/python/m3module.c index ed239f3..46116a9 100644 --- a/platforms/python/m3module.c +++ b/platforms/python/m3module.c @@ -274,7 +274,7 @@ M3_Function_call(m3_function *self, PyObject *args, PyObject *kwargs) static PyObject* Function_name(m3_function *self, void * closure) { - return PyUnicode_FromString(self->f->name); // TODO + return PyUnicode_FromString(GetFunctionName(self->f)); // TODO } static PyObject* diff --git a/source/m3_compile.c b/source/m3_compile.c index 55504c1..33bd868 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -2340,7 +2340,7 @@ M3Result Compile_Function (IM3Function io_function) IM3FuncType ft = io_function->funcType; M3Result result = m3Err_none; m3log (compile, "compiling: '%s'; wasm-size: %d; numArgs: %d; return: %s", - io_function->name, (u32) (io_function->wasmEnd - io_function->wasm), GetFunctionNumArgs (io_function), c_waTypes [GetSingleRetType(ft)]); + GetFunctionName(io_function), (u32) (io_function->wasmEnd - io_function->wasm), GetFunctionNumArgs (io_function), c_waTypes [GetSingleRetType(ft)]); IM3Runtime runtime = io_function->module->runtime; IM3Compilation o = & runtime->compilation; diff --git a/source/m3_config.h b/source/m3_config.h index e401f1e..79d5191 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -32,6 +32,10 @@ # define d_m3MaxConstantTableSize 120 # endif +# ifndef d_m3MaxDuplicateFunctionImpl +# define d_m3MaxDuplicateFunctionImpl 3 +# endif + # ifndef d_m3VerboseLogs # define d_m3VerboseLogs 1 # endif diff --git a/source/m3_env.c b/source/m3_env.c index ee78deb..1798056 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -41,10 +41,13 @@ void Function_Release (IM3Function i_function) { m3Free (i_function->constants); - // name can be an alias of fieldUtf8 - if (i_function->name != i_function->import.fieldUtf8) + for (int i = 0; i < i_function->numNames; i++) { - m3Free (i_function->name); + // name can be an alias of fieldUtf8 + if (i_function->names[i] != i_function->import.fieldUtf8) + { + m3Free (i_function->names[i]); + } } FreeImportInfo (& i_function->import); @@ -90,10 +93,30 @@ void Function_FreeCompiledCode (IM3Function i_function) cstr_t GetFunctionName (IM3Function i_function) { + u16 numNames = 0; + cstr_t *names = GetFunctionNames(i_function, &numNames); + if (numNames > 0) + return names[0]; + else + return ""; +} + + +cstr_t * GetFunctionNames (IM3Function i_function, u16 * o_numNames) +{ + if (o_numNames == NULL) + return NULL; + if (i_function->import.fieldUtf8) - return i_function->import.fieldUtf8; + { + *o_numNames = 1; + return &i_function->import.fieldUtf8; + } else - return (i_function->name) ? i_function->name : ""; + { + *o_numNames = i_function->numNames; + return i_function->names; + } } @@ -616,7 +639,7 @@ _ (m3ReallocArray (& io_module->table0, IM3Function, endElement, io_mo u32 functionIndex; _ (ReadLEB_u32 (& functionIndex, & bytes, end)); _throwif ("function index out of range", functionIndex >= io_module->numFunctions); - IM3Function function = & io_module->functions [functionIndex]; d_m3Assert (function); //printf ("table: %s\n", function->name); + IM3Function function = & io_module->functions [functionIndex]; d_m3Assert (function); //printf ("table: %s\n", GetFunctionName(function)); io_module->table0 [e + offset] = function; } } @@ -692,9 +715,12 @@ void * v_FindFunction (IM3Module i_module, const char * const i_name) bool isImported = f->import.moduleUtf8 or f->import.fieldUtf8; - if (not isImported and f->name) + if (isImported) + continue; + + for (int j = 0; j < f->numNames; j++) { - if (strcmp (f->name, i_name) == 0) + if (f->names [j] and strcmp (f->names [j], i_name) == 0) return f; } } diff --git a/source/m3_env.h b/source/m3_env.h index d4c5d49..d778b54 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -28,14 +28,15 @@ typedef struct M3Function bytes_t wasm; bytes_t wasmEnd; - cstr_t name; + u16 numNames; // maximum of d_m3MaxDuplicateFunctionImpl + cstr_t names[d_m3MaxDuplicateFunctionImpl]; IM3FuncType funcType; pc_t compiled; # if (d_m3EnableCodePageRefCounting) - IM3CodePage * codePageRefs; // array of all pages used + IM3CodePage * codePageRefs; // array of all pages used u32 numCodePageRefs; # endif @@ -47,7 +48,7 @@ typedef struct M3Function u16 numArgSlots; - u16 numLocals; // not including args + u16 numLocals; // not including args u16 numLocalBytes; void * constants; @@ -62,6 +63,7 @@ void Function_FreeCompiledCode (IM3Function i_function); cstr_t GetFunctionImportModuleName (IM3Function i_function); cstr_t GetFunctionName (IM3Function i_function); +cstr_t * GetFunctionNames (IM3Function i_function, u16 * o_numNames); u32 GetFunctionNumArgs (IM3Function i_function); u32 GetFunctionNumReturns (IM3Function i_function); diff --git a/source/m3_exec.h b/source/m3_exec.h index a70fe8b..9bdcf98 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -666,7 +666,7 @@ d_m3Op (Entry) if ((void *) ((m3slot_t *) _sp + function->maxStackSlots) < _mem->maxStack) #endif { - m3log (exec, " enter %p > %s %s", _pc - 2, function->name ? function->name : ".unnamed", SPrintFunctionArgList (function, _sp)); + m3log (exec, " enter %p > %s %s", _pc - 2, GetFunctionName(function), SPrintFunctionArgList (function, _sp)); #if defined(DEBUG) function->hits++; @@ -689,10 +689,10 @@ d_m3Op (Entry) if (not r) SPrintArg (str, 99, _sp, GetSingleRetType(function->funcType)); - m3log (exec, " exit < %s %s %s %s", function->name, function->funcType->numRets ? "->" : "", str, r ? (cstr_t)r : ""); + m3log (exec, " exit < %s %s %s %s", GetFunctionName(function), function->funcType->numRets ? "->" : "", str, r ? (cstr_t)r : ""); # elif d_m3LogStackTrace if (r) - printf (" ** %s %p\n", function->name, _sp); + printf (" ** %s %p\n", GetFunctionName(function), _sp); # endif return r; @@ -857,7 +857,7 @@ d_m3Op (DumpStack) u32 stackHeight = immediate (u32); IM3Function function = immediate (IM3Function); - cstr_t funcName = (function) ? function->name : ""; + cstr_t funcName = (function) ? GetFunctionName(function) : ""; printf (" %4d ", opcodeIndex); printf (" %-25s r0: 0x%016" PRIx64 " i:%" PRIi64 " u:%" PRIu64 "\n", funcName, _r0, _r0, _r0); diff --git a/source/m3_info.c b/source/m3_info.c index 3e38b72..70c82b5 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -201,7 +201,8 @@ d_m3Decoder (Entry) { IM3Function function = fetch (IM3Function); - sprintf (o_string, "%s", function->name); + // only prints out the first registered name for the function + sprintf (o_string, "%s", GetFunctionName(function)); } diff --git a/source/m3_module.c b/source/m3_module.c index 6d84731..8a6c662 100644 --- a/source/m3_module.c +++ b/source/m3_module.c @@ -77,10 +77,11 @@ _ (m3ReallocArray (& io_module->functions, M3Function, io_module->numFunctions IM3Function func = Module_GetFunction (io_module, index); func->funcType = ft; - if (i_importInfo) + if (i_importInfo and func->numNames == 0) { func->import = * i_importInfo; - func->name = i_importInfo->fieldUtf8; + func->numNames = 1; + func->names[0] = i_importInfo->fieldUtf8; } // m3log (module, " added function: %3d; sig: %d", index, i_typeIndex); diff --git a/source/m3_parse.c b/source/m3_parse.c index eceb18c..a452e8d 100644 --- a/source/m3_parse.c +++ b/source/m3_parse.c @@ -228,9 +228,11 @@ _ (ReadLEB_u32 (& index, & i_bytes, i_end)); if (exportKind == d_externalKind_function) { _throwif(m3Err_wasmMalformed, index >= io_module->numFunctions); - if (not io_module->functions [index].name) + u16 numNames = io_module->functions [index].numNames; + if (numNames < d_m3MaxDuplicateFunctionImpl - 1) { - io_module->functions [index].name = utf8; + io_module->functions [index].numNames++; + io_module->functions [index].names[numNames] = utf8; utf8 = NULL; // ownership transfered to M3Function } } @@ -478,9 +480,10 @@ _ (Read_utf8 (& name, & i_bytes, i_end)); if (index < io_module->numFunctions) { - if (not io_module->functions [index].name) + if (io_module->functions [index].numNames == 0) { - io_module->functions [index].name = name; m3log (parse, " naming function%5d: %s", index, name); + io_module->functions [index].numNames = 1; + io_module->functions [index].names[0] = name; m3log (parse, " naming function%5d: %s", index, name); name = NULL; // transfer ownership } // else m3log (parse, "prenamed: %s", io_module->functions [index].name);