diff --git a/source/m3_api_wasi.c b/source/m3_api_wasi.c index ad55f65..a47c773 100644 --- a/source/m3_api_wasi.c +++ b/source/m3_api_wasi.c @@ -250,7 +250,7 @@ m3ApiRawFunction(m3_wasi_unstable_fd_prestat_dir_name) if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); } - int size = M3_MIN(strlen(preopen[fd].path), path_len); + int size = m3_min (strlen(preopen[fd].path), path_len); memcpy(path, preopen[fd].path, size); m3ApiReturn(__WASI_ESUCCESS); } @@ -543,7 +543,7 @@ m3ApiRawFunction(m3_wasi_unstable_random_get) ssize_t retlen = 0; #if defined(__wasi__) || defined(__APPLE__) || defined(__ANDROID_API__) || defined(__OpenBSD__) - size_t reqlen = M3_MIN(buflen, 256); + size_t reqlen = m3_min (buflen, 256); # if defined(__APPLE__) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) retlen = SecRandomCopyBytes(kSecRandomDefault, reqlen, buf) < 0 ? -1 : reqlen; # else diff --git a/source/m3_compile.c b/source/m3_compile.c index e13fb7e..0917a53 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -16,6 +16,8 @@ static const IM3Operation c_setSetOps [] = { NULL, op_SetSlot_i32, op_SetSlot_i64, op_SetSlot_f32, op_SetSlot_f64 }; +static const u16 c_slotUnused = 0xffff; + #define d_indent " | " // just want less letter and numbers to stare at down the way in the compiler table @@ -142,8 +144,6 @@ bool IsStackTopInSlot (IM3Compilation o) } -static const u16 c_slotUnused = 0xffff; - u16 GetStackTopSlotIndex (IM3Compilation o) { i16 i = GetStackTopIndex (o); d_m3Assert (i >= 0 or IsStackPolymorphic (o)); @@ -167,7 +167,7 @@ bool IsValidSlot (u16 i_slot) void MarkSlotAllocated (IM3Compilation o, u16 i_slot) { d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated o->m3Slots [i_slot] = 1; - o->numAllocatedExecSlots++; + o->numAllocatedSlots++; } @@ -217,7 +217,7 @@ void DeallocateSlot (IM3Compilation o, i16 i_slotIndex, u8 i_type) for (u32 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex) { if (-- o->m3Slots [i_slotIndex] == 0) - o->numAllocatedExecSlots--; + o->numAllocatedSlots--; } } @@ -262,7 +262,7 @@ u16 GetMaxExecSlot (IM3Compilation o) { u16 i = o->firstSlotIndex; - u32 allocated = o->numAllocatedExecSlots; + u32 allocated = o->numAllocatedSlots; while (i < d_m3MaxFunctionStackHeight) { @@ -349,7 +349,7 @@ _ (PreserveRegisterIfOccupied (o, c_m3Type_f64)); //---------------------------------------------------------------------------------------------------------------------- -M3Result Push (IM3Compilation o, u8 i_type, i16 i_location) +M3Result Push (IM3Compilation o, u8 i_type, u16 i_location) { M3Result result = m3Err_none; @@ -357,13 +357,6 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location) if (stackIndex < d_m3MaxFunctionStackHeight) { - if (o->function) - { - // op_Entry uses this value to track and detect stack overflow - if (stackIndex > o->function->maxStackSlots) - o->function->maxStackSlots = stackIndex; - } - o->wasmStack [stackIndex] = i_location; o->typeStack [stackIndex] = i_type; @@ -371,7 +364,17 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location) { u32 regSelect = IsFpRegisterLocation (i_location); AllocateRegister (o, regSelect, stackIndex); - } m3logif (stack, dump_type_stack (o)) + } + else + { + if (o->function) + { + // op_Entry uses this value to track and detect stack overflow + o->function->maxStackSlots = m3_max (o->function->maxStackSlots, i_location + 1); + } + } + + m3logif (stack, dump_type_stack (o)) } else result = m3Err_functionStackOverflow; @@ -381,7 +384,7 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location) M3Result PushRegister (IM3Compilation o, u8 i_type) { - i16 location = IsFpType (i_type) ? d_m3Fp0SlotAlias : d_m3Reg0SlotAlias; d_m3Assert (i_type or IsStackPolymorphic (o)); + u16 location = IsFpType (i_type) ? d_m3Fp0SlotAlias : d_m3Reg0SlotAlias; d_m3Assert (i_type or IsStackPolymorphic (o)); return Push (o, i_type, location); } @@ -656,13 +659,15 @@ _ (EmitOp (o, op)); M3Result MoveStackTopToRegister (IM3Compilation o) { + static const IM3Operation setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 }; + M3Result result = m3Err_none; if (IsStackTopInSlot (o)) { u8 type = GetStackTopType (o); - static const IM3Operation setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 }; +_ (PreserveRegisterIfOccupied (o, type)); IM3Operation op = setRegisterOps [type]; @@ -764,9 +769,9 @@ M3Result Compile_Const_i32 (IM3Compilation o, u8 i_opcode) M3Result result; i32 value; -_ (ReadLEB_i32 (& value, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const i32 = %" PRIi32 ")", get_indention_string (o), value); -_ (PushConst (o, value, c_m3Type_i32)); - +_ (ReadLEB_i32 (& value, & o->wasm, o->wasmEnd)); +_ (PushConst (o, value, c_m3Type_i32)); m3log (compile, d_indent "%s (const i32 = %" PRIi32 "; slot: %d)", + get_indention_string (o), value, GetStackTopSlotIndex (o)); _catch: return result; } @@ -776,9 +781,9 @@ M3Result Compile_Const_i64 (IM3Compilation o, u8 i_opcode) M3Result result; i64 value; -_ (ReadLEB_i64 (& value, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const i64 = %" PRIi64 ")", get_indention_string (o), value); -_ (PushConst (o, value, c_m3Type_i64)); - +_ (ReadLEB_i64 (& value, & o->wasm, o->wasmEnd)); +_ (PushConst (o, value, c_m3Type_i64)); m3log (compile, d_indent "%s (const i64 = %" PRIi64 "; slot: %d)", + get_indention_string (o), value, GetStackTopSlotIndex (o)); _catch: return result; } @@ -787,9 +792,9 @@ M3Result Compile_Const_f32 (IM3Compilation o, u8 i_opcode) { M3Result result; - union { u64 u; f32 f; } value = { 0 }; + union { u32 u; f32 f; } value = { 0 }; -_ (Read_f32 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f32 = %f)", get_indention_string (o), value); +_ (Read_f32 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f32 = %f)", get_indention_string (o), value.f); _ (PushConst (o, value.u, c_m3Type_f32)); _catch: return result; @@ -802,7 +807,7 @@ M3Result Compile_Const_f64 (IM3Compilation o, u8 i_opcode) union { u64 u; f64 f; } value = { 0 }; -_ (Read_f64 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f64 = %lf)", get_indention_string (o), value); +_ (Read_f64 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f64 = %lf)", get_indention_string (o), value.f); _ (PushConst (o, value.u, c_m3Type_f64)); _catch: return result; @@ -1507,7 +1512,8 @@ _ (PushRegister (o, type)); M3Result Compile_Drop (IM3Compilation o, u8 i_opcode) { - return Pop (o); + M3Result result = Pop (o); m3logif (stack, dump_type_stack (o)) + return result; } @@ -1650,7 +1656,7 @@ _ (ReadLEB_u32 (& memoryOffset, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (offset = %d)", get_indention_string (o), memoryOffset); const M3OpInfo * op = & c_operations [i_opcode]; - if (IsFpType (op->type)) // loading a float? + if (IsFpType (op->type)) _ (PreserveRegisterIfOccupied (o, c_m3Type_f64)); _ (Compile_Operator (o, i_opcode)); @@ -2071,7 +2077,7 @@ M3Result Compile_ReserveConstants (IM3Compilation o) // if constants overflow their reserved stack space, the compiler simply emits op_Const // operations as needed. Compiled expressions (global inits) don't pass through this // ReserveConstants function and thus always produce inline contants. - numConstants = M3_MIN (numConstants, d_m3MaxNumFunctionConstants); + numConstants = m3_min (numConstants, d_m3MaxNumFunctionConstants); u32 freeSlots = d_m3MaxFunctionStackHeight - o->constSlotIndex; @@ -2130,7 +2136,7 @@ _ (Compile_ReserveConstants (o)); // start tracking the max stack used (Push() also updates this value) so that op_Entry can precisely detect stack overflow o->function->maxStackSlots = o->firstSlotIndex; - o->numAllocatedExecSlots = 0; // this var only tracks dynamic slots so clear local+constant allocations + o->numAllocatedSlots = 0; // this var only tracks dynamic slots so clear local+constant allocations o->block.initStackIndex = o->stackIndex; _ (EmitOp (o, op_Entry)); diff --git a/source/m3_compile.h b/source/m3_compile.h index d570c99..6777fbe 100644 --- a/source/m3_compile.h +++ b/source/m3_compile.h @@ -98,7 +98,7 @@ typedef struct // 'm3Slots' contains allocation usage counts u8 m3Slots [d_m3MaxFunctionStackHeight]; - u16 numAllocatedExecSlots; + u16 numAllocatedSlots; u16 regStackIndexPlusOne [2]; @@ -152,11 +152,6 @@ bool IsIntRegisterLocation (i16 i_location); bool IsStackPolymorphic (IM3Compilation o); -M3Result EmitOp (IM3Compilation o, IM3Operation i_operation); -void EmitConstant (IM3Compilation o, const u64 immediate); -M3Result Push (IM3Compilation o, u8 i_waType, i16 i_location); -void EmitPointer (IM3Compilation o, const void * const i_immediate); - M3Result CompileBlock (IM3Compilation io, u8 i_blockType, u8 i_blockOpcode); M3Result Compile_BlockStatements (IM3Compilation io); diff --git a/source/m3_config.h b/source/m3_config.h index 1d7b76a..47c4e48 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -21,6 +21,8 @@ # define d_m3MaxFunctionStackHeight 2000 # endif +#define d_m3MaxNumFunctionConstants 60 + # ifndef d_m3LogOutput # define d_m3LogOutput 1 # endif @@ -52,16 +54,16 @@ // m3log (...) ---------------------------------------------------------------- -# define d_m3LogParse 0 -# define d_m3LogCompile 0 -# define d_m3LogWasmStack 0 -# define d_m3LogEmit 0 -# define d_m3LogCodePages 0 -# define d_m3LogModule 0 -# define d_m3LogRuntime 0 -# define d_m3LogExec 0 -# define d_m3LogStackTrace 0 -# define d_m3LogNativeStack 0 +# define d_m3LogParse 0 // .wasm binary decoding info +# define d_m3LogModule 0 // Wasm module info +# define d_m3LogCompile 0 // wasm -> metacode generation phase +# define d_m3LogWasmStack 0 // dump the wasm stack when pushed or popped +# define d_m3LogEmit 0 // metacode generation info +# define d_m3LogCodePages 0 // dump metacode pages when released +# define d_m3LogExec 0 // low-level interpreter specific logs +# define d_m3LogRuntime 0 // higher-level runtime information +# define d_m3LogStackTrace 0 // dump the call stack when traps occur +# define d_m3LogNativeStack 0 // track the memory usage of the C-stack // other ---------------------------------------------------------------------- diff --git a/source/m3_config_platforms.h b/source/m3_config_platforms.h index 805dcff..3db7408 100644 --- a/source/m3_config_platforms.h +++ b/source/m3_config_platforms.h @@ -178,11 +178,11 @@ # define M3_WEAK __attribute__((weak)) # endif -# ifndef M3_MIN -# define M3_MIN(A,B) (((A) < (B)) ? (A) : (B)) +# ifndef m3_min +# define m3_min(A,B) (((A) < (B)) ? (A) : (B)) # endif -# ifndef M3_MAX -# define M3_MAX(A,B) (((A) > (B)) ? (A) : (B)) +# ifndef m3_max +# define m3_max(A,B) (((A) > (B)) ? (A) : (B)) # endif #define M3_INIT(field) memset(&field, 0, sizeof(field)) diff --git a/source/m3_core.c b/source/m3_core.c index d48336e..04db810 100644 --- a/source/m3_core.c +++ b/source/m3_core.c @@ -173,7 +173,7 @@ void m3StackCheck () size_t addr = (size_t)&stack; size_t stackEnd = stack_end; - stack_end = M3_MIN(stack_end, addr); + stack_end = m3_min (stack_end, addr); // if (stackEnd != stack_end) // printf ("maxStack: %ld\n", m3StackGetMax ()); diff --git a/source/m3_core.h b/source/m3_core.h index 8febc8d..0b45eff 100644 --- a/source/m3_core.h +++ b/source/m3_core.h @@ -154,10 +154,8 @@ M3CodePageHeader; #define d_m3MemPageSize 65536 -#define d_m3Reg0SlotAlias d_m3MaxFunctionStackHeight + 1 -#define d_m3Fp0SlotAlias d_m3MaxFunctionStackHeight + 2 - -#define d_m3MaxNumFunctionConstants 60 +#define d_m3Reg0SlotAlias 30000 +#define d_m3Fp0SlotAlias 30001 #define d_m3MaxSaneUtf8Length 2000 diff --git a/source/m3_env.c b/source/m3_env.c index 2fa99cb..71fb242 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -298,7 +298,7 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages) // Limit the amount of memory that gets allocated if (io_runtime->memoryLimit) { - numPageBytes = M3_MIN(numPageBytes, io_runtime->memoryLimit); + numPageBytes = m3_min (numPageBytes, io_runtime->memoryLimit); } size_t numBytes = numPageBytes + sizeof (M3MemoryHeader); @@ -321,7 +321,7 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages) memory->mallocated->maxStack = (m3reg_t *) io_runtime->stack + io_runtime->numStackSlots; - m3log (runtime, "resized old: %p; mem: %p; length: %z; pages: %d", oldMallocated, memory->mallocated, memory->mallocated->length, memory->numPages); + m3log (runtime, "resized old: %p; mem: %p; length: %zu; pages: %d", oldMallocated, memory->mallocated, memory->mallocated->length, memory->numPages); } else result = m3Err_mallocFailed; } diff --git a/source/m3_info.c b/source/m3_info.c index 220d686..8b45ef9 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -92,7 +92,7 @@ size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type) else if (i_type == c_m3Type_f64) len = snprintf (o_string, i_n, "%lf", * (f64 *) i_sp); - len = M3_MAX (0, len); + len = m3_max (0, len); return len; } @@ -105,7 +105,7 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp) char * s = string; ccstr_t e = string + sizeof(string) - 1; - s += M3_MAX (0, snprintf (s, e-s, "(")); + s += m3_max (0, snprintf (s, e-s, "(")); IM3FuncType funcType = i_function->funcType; if (funcType) @@ -117,17 +117,17 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp) { u8 type = types [i]; - s += M3_MAX (0, snprintf (s, e-s, "%s: ", c_waTypes [type])); + s += m3_max (0, snprintf (s, e-s, "%s: ", c_waTypes [type])); s += SPrintArg (s, e-s, i_sp + i, type); if (i != numArgs - 1) - s += M3_MAX (0, snprintf (s, e-s, ", ")); + s += m3_max (0, snprintf (s, e-s, ", ")); } } else printf ("null signature"); - s += M3_MAX (0, snprintf (s, e-s, ")")); + s += m3_max (0, snprintf (s, e-s, ")")); return string; } diff --git a/source/m3_parse.c b/source/m3_parse.c index 444a1fe..19e3fce 100644 --- a/source/m3_parse.c +++ b/source/m3_parse.c @@ -235,7 +235,7 @@ M3Result ParseSection_Start (IM3Module io_module, bytes_t i_bytes, cbytes_t i_ M3Result result = m3Err_none; u32 startFuncIndex; -_ (ReadLEB_u32 (& startFuncIndex, & i_bytes, i_end)); m3log (parse, "** Start Function: %d", startFunc); +_ (ReadLEB_u32 (& startFuncIndex, & i_bytes, i_end)); m3log (parse, "** Start Function: %d", startFuncIndex); if (startFuncIndex < io_module->numFunctions) { @@ -310,22 +310,22 @@ _ (ReadLEB_u32 (& size, & i_bytes, i_end)); { const u8 * start = ptr; - u32 numLocals; -_ (ReadLEB_u32 (& numLocals, & ptr, i_end)); m3log (parse, " - func size: %d; locals: %d", size, numLocals); + u32 numLocalBlocks; +_ (ReadLEB_u32 (& numLocalBlocks, & ptr, i_end)); m3log (parse, " - func size: %d; local blocks: %d", size, numLocalBlocks); - u32 numLocalVars = 0; + u32 numLocals = 0; - for (u32 l = 0; l < numLocals; ++l) + for (u32 l = 0; l < numLocalBlocks; ++l) { u32 varCount; - i8 varType; - u8 normalizedType; + i8 wasmType; + u8 normalType; _ (ReadLEB_u32 (& varCount, & ptr, i_end)); -_ (ReadLEB_i7 (& varType, & ptr, i_end)); -_ (NormalizeType (& normalizedType, varType)); +_ (ReadLEB_i7 (& wasmType, & ptr, i_end)); +_ (NormalizeType (& normalType, wasmType)); - numLocalVars += varCount; m3log (parse, " - %d locals; type: '%s'", varCount, c_waTypes [-varType]); + numLocals += varCount; m3log (parse, " - %d locals; type: '%s'", varCount, c_waTypes [normalType]); } IM3Function func = Module_GetFunction (io_module, f + io_module->numImports); @@ -333,7 +333,7 @@ _ (NormalizeType (& normalizedType, varType)); func->module = io_module; func->wasm = start; func->wasmEnd = i_bytes; - func->numLocals = numLocalVars; + func->numLocals = numLocals; } else _throw (m3Err_wasmSectionOverrun); } diff --git a/source/wasm3.h b/source/wasm3.h index 1bd3fd9..3bb6fe3 100644 --- a/source/wasm3.h +++ b/source/wasm3.h @@ -123,7 +123,7 @@ d_m3ErrorConst (functionImportMissing, "missing imported function") // compilation errors d_m3ErrorConst (noCompiler, "no compiler found for opcode") d_m3ErrorConst (unknownOpcode, "unknown opcode") -d_m3ErrorConst (functionStackOverflow, "compiling function overrun its stack height limit") +d_m3ErrorConst (functionStackOverflow, "compiling function overran its stack height limit") d_m3ErrorConst (functionStackUnderrun, "compiling function underran the stack") d_m3ErrorConst (mallocFailedCodePage, "memory allocation failed when acquiring a new M3 code page") d_m3ErrorConst (settingImmutableGlobal, "attempting to set an immutable global")