diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b882400..1edc4cb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,14 +18,17 @@ jobs: fail-fast: false matrix: config: - - {target: wasm3-win-x64, platform: "-A x64", toolset: "-T ClangCL" } - - {target: wasm3-win-x86, platform: "-A Win32", toolset: "-T ClangCL" } + - {target: wasm3-win-x64, platform: "-A x64", toolset: "-T ClangCL" } + - {target: wasm3-win-x86, platform: "-A Win32", toolset: "-T ClangCL" } + - {target: wasm3-strace-win-x64, platform: "-A x64", toolset: "-T ClangCL", cflags: "-DDEBUG -Dd_m3EnableStrace=2 -Dd_m3RecordBacktraces=1" } env: LDFLAGS: -s steps: - uses: actions/checkout@v2 - name: Configure + env: + CFLAGS: ${{ matrix.config.cflags }} run: | mkdir build cd build diff --git a/source/m3_compile.c b/source/m3_compile.c index e3085e5..eaeba33 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -329,6 +329,15 @@ u16 GetMaxUsedSlotPlusOne (IM3Compilation o) o->slotMaxAllocatedIndexPlusOne--; } + +# ifdef DEBUG + u16 maxSlot = o->slotMaxAllocatedIndexPlusOne; + while (maxSlot < d_m3MaxFunctionSlots) + { + d_m3Assert (o->m3Slots [maxSlot] == 0); + maxSlot++; + } +# endif return o->slotMaxAllocatedIndexPlusOne; } @@ -2374,6 +2383,8 @@ void SetupCompilation (IM3Compilation o) M3Result CompileFunction (IM3Function io_function) { + if (!io_function->wasm) return "function body is missing"; + IM3FuncType funcType = io_function->funcType; M3Result result = m3Err_none; m3log (compile, "compiling: '%s'; wasm-size: %d; numArgs: %d; return: %s", diff --git a/source/m3_env.h b/source/m3_env.h index 9d3a12f..5f5c482 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -89,9 +89,7 @@ typedef struct M3Module u32 numFuncTypes; IM3FuncType * funcTypes; // array of pointers to list of FuncTypes - u32 numImports; - //IM3Function * imports; b // notice: "I" prefix. imports are pointers to functions in another module. - + u32 numFuncImports; u32 numFunctions; M3Function * functions; diff --git a/source/m3_module.c b/source/m3_module.c index f5abac6..82e68d6 100644 --- a/source/m3_module.c +++ b/source/m3_module.c @@ -34,6 +34,10 @@ void m3_FreeModule (IM3Module i_module) m3_Free (i_module->dataSegments); m3_Free (i_module->table0); + for (u32 i = 0; i < i_module->numGlobals; ++i) + { + m3_Free (i_module->globals[i].name); + } for (u32 i = 0; i < i_module->numGlobals; ++i) { FreeImportInfo(&(i_module->globals[i].import)); @@ -105,7 +109,7 @@ IM3Function Module_GetFunction (IM3Module i_module, u32 i_functionIndex) if (i_functionIndex < i_module->numFunctions) { func = & i_module->functions [i_functionIndex]; - func->module = i_module; + //func->module = i_module; } return func; diff --git a/source/m3_parse.c b/source/m3_parse.c index e66b0be..ee7f3a2 100644 --- a/source/m3_parse.c +++ b/source/m3_parse.c @@ -168,7 +168,7 @@ _ (ReadLEB_u32 (& typeIndex, & i_bytes, i_end)) _ (Module_AddFunction (io_module, typeIndex, & import)) import = clearImport; - io_module->numImports++; + io_module->numFuncImports++; } break; @@ -324,7 +324,7 @@ M3Result ParseSection_Code (M3Module * io_module, bytes_t i_bytes, cbytes_t i_ u32 numFunctions; _ (ReadLEB_u32 (& numFunctions, & i_bytes, i_end)); m3log (parse, "** Code [%d]", numFunctions); - if (numFunctions != io_module->numFunctions - io_module->numImports) + if (numFunctions != io_module->numFunctions - io_module->numFuncImports) { _throw ("mismatched function count in code section"); } @@ -361,7 +361,7 @@ _ (NormalizeType (& normalType, wasmType)); numLocals += varCount; m3log (parse, " %2d locals; type: '%s'", varCount, c_waTypes [normalType]); } - IM3Function func = Module_GetFunction (io_module, f + io_module->numImports); + IM3Function func = Module_GetFunction (io_module, f + io_module->numFuncImports); func->module = io_module; func->wasm = start; @@ -411,6 +411,8 @@ _ (ReadLEB_u32 (& segment->size, & i_bytes, i_end)); segment->data = i_bytes; m3log (parse, " segment [%u] memory: %u; expr-size: %d; size: %d", i, segment->memoryRegion, segment->initExprSize, segment->size); i_bytes += segment->size; + + _throwif("data segment underflow", i_bytes > i_end); } _catch: @@ -591,33 +593,32 @@ _ (Read_u32 (& version, & pos, end)); _throwif (m3Err_wasmMalformed, magic != 0x6d736100); _throwif (m3Err_incompatibleWasmVersion, version != 1); - m3log (parse, "found magic + version"); - u8 previousSection = 0; + + static const u8 sectionsOrder[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 10, 11, 0 }; // 0 is a placeholder + u8 expectedSection = 0; while (pos < end) { u8 section; _ (ReadLEB_u7 (& section, & pos, end)); - if (section > previousSection or // from the spec: sections must appear in order - section == 0 or // custom section - (section == 12 and previousSection == 9) or // if present, DataCount goes after Element - (section == 10 and previousSection == 12)) // and before Code - { - u32 sectionLength; -_ (ReadLEB_u32 (& sectionLength, & pos, end)); - _throwif(m3Err_wasmMalformed, pos + sectionLength > end); -_ (ParseModuleSection (module, section, pos, sectionLength)); + if (section != 0) { + // Ensure sections appear only once and in order + while (sectionsOrder[expectedSection++] != section) { + _throwif(m3Err_misorderedWasmSection, expectedSection >= 12); + } + } - pos += sectionLength; + u32 sectionLength; +_ (ReadLEB_u32 (& sectionLength, & pos, end)); + _throwif(m3Err_wasmMalformed, pos + sectionLength > end); - if (section) - previousSection = section; - } - else _throw (m3Err_misorderedWasmSection); +_ (ParseModuleSection (module, section, pos, sectionLength)); + + pos += sectionLength; } - } _catch: +} _catch: if (result) {