diff --git a/source/m3_compile.c b/source/m3_compile.c index 00aab96..9a505bc 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -50,9 +50,12 @@ i16 GetNumBlockValues (IM3Compilation o) { return o->stackIndex - o-> u16 GetTypeNumSlots (u8 i_type) { -// return 1; - u16 n = Is64BitType (i_type) ? 2 : 1; - return n; +# if d_m3Use32BitSlots + u16 n = Is64BitType (i_type) ? 2 : 1; + return n; +# else + return 1; +# endif } i16 GetStackTopIndex (IM3Compilation o) @@ -177,8 +180,9 @@ M3Result AllocateSlotsWithinRange (IM3Compilation o, u16 * o_slot, u8 i_type, u16 numSlots = GetTypeNumSlots (i_type); u16 searchOffset = numSlots - 1; - - AlignSlotIndexToType (& i_startSlot, i_type); + + if (d_m3Use32BitSlots) + AlignSlotIndexToType (& i_startSlot, i_type); // search for 1 or 2 consecutive slots in the execution stack u16 i = i_startSlot; @@ -539,7 +543,7 @@ _ (Push (o, i_type, slot)); { result = m3Err_none; -_ (EmitOp (o, numRequiredSlots == 1 ? op_Const32 : op_Const64)); +_ (EmitOp (o, Is64BitType (i_type) ? op_Const64 : op_Const32)); EmitConstant64 (o, i_word); _ (PushAllocatedSlotAndEmit (o, i_type)); } @@ -547,7 +551,7 @@ _ (PushAllocatedSlotAndEmit (o, i_type)); { u16 constTableIndex = slot - o->firstConstSlotIndex; - if (numRequiredSlots == 2) + if (Is64BitType (i_type)) { u64 * constant64 = (u64 *) & o->constants [constTableIndex]; * constant64 = i_word; @@ -618,6 +622,9 @@ bool PatchBranches (IM3Compilation o) while (patches) { m3log (compile, "patching location: %p to pc: %p", patches->location, pc); + if (not patches->location) + break; + * (patches->location) = pc; endPatch = patches; @@ -1220,8 +1227,6 @@ void AlignSlotIndexToType (u16 * io_slotIndex, u8 i_type) // align 64-bit words to even slots u16 numSlots = GetTypeNumSlots (i_type); -// printf ("%d\n", (u32) numSlots); - u16 mask = numSlots - 1; * io_slotIndex = (* io_slotIndex + mask) & ~mask; } @@ -1251,12 +1256,14 @@ _ (Pop (o)); u32 numArgs = i_type->numArgs; + u32 slotsPerArg = sizeof (u64) / sizeof (m3slot_t); + // args are 64-bit aligned - u16 argTop = topSlot + numArgs * 2; + u16 argTop = topSlot + numArgs * slotsPerArg; while (numArgs--) { -_ (CopyTopSlot (o, argTop -= 2)); +_ (CopyTopSlot (o, argTop -= slotsPerArg)); _ (Pop (o)); } @@ -1803,7 +1810,7 @@ const M3OpInfo c_operations [] = M3OP( "local.get", 1, any, d_emptyOpList, Compile_GetLocal ), // 0x20 M3OP( "local.set", 1, none, d_emptyOpList, Compile_SetLocal ), // 0x21 M3OP( "local.tee", 0, any, d_emptyOpList, Compile_SetLocal ), // 0x22 - M3OP( "global.get", 1, none, d_logOp2 (GetGlobal_s32, GetGlobal_s64), Compile_GetSetGlobal ), // 0x23 + M3OP( "global.get", 1, none, d_emptyOpList, Compile_GetSetGlobal ), // 0x23 M3OP( "global.set", 1, none, d_emptyOpList, Compile_GetSetGlobal ), // 0x24 M3OP_RESERVED, M3OP_RESERVED, M3OP_RESERVED, // 0x25 - 0x27 @@ -1999,6 +2006,8 @@ const M3OpInfo c_operations [] = # define d_m3DebugTypedOp(OP) M3OP (#OP, 0, none, { op_##OP##_i32, op_##OP##_i64, op_##OP##_f32, op_##OP##_f64, }) d_m3DebugOp (Entry), d_m3DebugOp (Compile), d_m3DebugOp (End), + + d_m3DebugOp (GetGlobal_s32), d_m3DebugOp (GetGlobal_s64), d_m3DebugOp (ContinueLoop), d_m3DebugOp (ContinueLoopIf), @@ -2195,7 +2204,7 @@ M3Result Compile_Function (IM3Function io_function) 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 [GetFunctionReturnType (io_function)]); IM3Runtime runtime = io_function->module->runtime; - + IM3Compilation o = & runtime->compilation; SetupCompilation (o); @@ -2262,11 +2271,11 @@ _ (Compile_BlockStatements (o)); u32 numConstantSlots = o->maxConstSlotIndex - o->firstConstSlotIndex; m3log (compile, "unique constant slots: %d; unused slots: %d", numConstantSlots, o->firstDynamicSlotIndex - o->maxConstSlotIndex); - io_function->numConstantBytes = numConstantSlots * sizeof (u32); + io_function->numConstantBytes = numConstantSlots * sizeof (m3slot_t); if (numConstantSlots) { -_ (m3Alloc (& io_function->constants, u32, numConstantSlots)); +_ (m3Alloc (& io_function->constants, m3slot_t, numConstantSlots)); memcpy (io_function->constants, o->constants, io_function->numConstantBytes); } diff --git a/source/m3_compile.h b/source/m3_compile.h index 2421e65..974c498 100644 --- a/source/m3_compile.h +++ b/source/m3_compile.h @@ -61,8 +61,8 @@ M3CompilationScope; typedef M3CompilationScope * IM3CompilationScope; - -static const u16 c_m3MaxFunctionSlots = d_m3MaxFunctionStackHeight * 2; +// double the slot count when using 32-bit slots, since every wasm stack element could be a 64-bit type +static const u16 c_m3MaxFunctionSlots = d_m3MaxFunctionStackHeight * (d_m3Use32BitSlots + 1); typedef struct { @@ -92,7 +92,7 @@ typedef struct u16 firstLocalSlotIndex; u16 firstDynamicSlotIndex; // numArgs + numLocals + numReservedConstants. the first mutable slot available to the compiler. - u32 constants [d_m3MaxConstantTableSize]; + m3slot_t constants [d_m3MaxConstantTableSize]; // 'wasmStack' holds slot locations u16 wasmStack [d_m3MaxFunctionStackHeight]; diff --git a/source/m3_config.h b/source/m3_config.h index 63318e7..4254c86 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -40,10 +40,14 @@ # define d_m3FixedHeapAlign 16 # endif -# ifndef d_m3EnableOptimizations -# define d_m3EnableOptimizations 0 +# ifndef d_m3Use32BitSlots +# define d_m3Use32BitSlots 0 # endif +//# ifndef d_m3EnableOptimizations +//# define d_m3EnableOptimizations 0 +//# endif + // logging -------------------------------------------------------------------- # define d_m3EnableOpProfiling 0 @@ -57,9 +61,9 @@ # define d_m3LogParse 0 // .wasm binary decoding info # define d_m3LogModule 0 // Wasm module info # define d_m3LogCompile 1 // wasm -> metacode generation phase -# define d_m3LogWasmStack 1 // dump the wasm stack when pushed or popped +# 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_m3LogCodePages 1 // dump metacode pages when released # define d_m3LogExec 1 // low-level interpreter specific logs # define d_m3LogRuntime 0 // higher-level runtime information # define d_m3LogStackTrace 0 // dump the call stack when traps occur diff --git a/source/m3_core.c b/source/m3_core.c index 3c984bd..edff408 100644 --- a/source/m3_core.c +++ b/source/m3_core.c @@ -116,20 +116,19 @@ M3Result m3Malloc (void ** o_ptr, size_t i_size) else result = m3Err_mallocFailed; * o_ptr = ptr; - //printf("== alloc %d => %p\n", i_size, ptr); +// printf("== alloc %d => %p\n", (u32) i_size, ptr); return result; } void m3Free_impl (void * i_ptr) { - //printf("== free %p\n", o_ptr); +// if (i_ptr) printf("== free %p\n", i_ptr); free (i_ptr); } void * m3Realloc (void * i_ptr, size_t i_newSize, size_t i_oldSize) { - //printf("== realloc %p => %d\n", i_ptr, i_newSize); void * ptr = i_ptr; if (i_newSize != i_oldSize) @@ -145,6 +144,8 @@ void * m3Realloc (void * i_ptr, size_t i_newSize, size_t i_oldSize) } else memset (ptr, 0x0, i_newSize); } + +// printf("== realloc %p -> %p => %d\n", i_ptr, ptr, (u32) i_newSize); } return ptr; diff --git a/source/m3_core.h b/source/m3_core.h index a8bff25..e5a1ce2 100644 --- a/source/m3_core.h +++ b/source/m3_core.h @@ -48,7 +48,13 @@ typedef const u8 * bytes_t; typedef const u8 * const cbytes_t; typedef i64 m3reg_t; + +# if d_m3Use32BitSlots typedef u32 m3slot_t; +# else +typedef u64 m3slot_t; +# endif + typedef m3slot_t * m3stack_t; typedef diff --git a/source/m3_env.c b/source/m3_env.c index 3a9ec13..2d60481 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -426,7 +426,7 @@ _ (ReadLEB_u32 (& numElements, & bytes, end)); if (endElement > offset) // TODO: check this, endElement depends on offset { - io_module->table0 = (IM3Function*)m3ReallocArray (io_module->table0, IM3Function, endElement, io_module->table0Size); + io_module->table0 = (IM3Function*) m3ReallocArray (io_module->table0, IM3Function, endElement, io_module->table0Size); if (io_module->table0) { @@ -569,11 +569,13 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char i_argc = 0; IM3FuncType ftype = i_function->funcType; m3logif (runtime, PrintFuncTypeSignature (ftype)); - u64 * stack = (u64 *) runtime->stack; if (i_argc != ftype->numArgs) _throw (m3Err_argumentCountMismatch); + // args are always 64-bit aligned + u64 * stack = (u64 *) runtime->stack; + // The format is currently not user-friendly by default, // as this is used in spec tests for (u32 i = 0; i < ftype->numArgs; ++i) diff --git a/source/m3_exec.c b/source/m3_exec.c index cd1cf0c..61f2219 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -199,15 +199,15 @@ d_m3OpDef (Entry) IM3Function function = immediate (IM3Function); -#if defined(d_m3SkipStackCheck) +#if defined (d_m3SkipStackCheck) if (true) #else - if ((void*)(_sp + function->maxStackSlots) < _mem->maxStack) + if ((void *) ((m3slot_t *) _sp + function->maxStackSlots) < _mem->maxStack) #endif { function->hits++; m3log (exec, " enter %p > %s %s", _pc - 2, function->name ? function->name : ".unnamed", SPrintFunctionArgList (function, _sp)); - u8 * stack = (u8 *) (_sp + function->numArgSlots); + u8 * stack = (u8 *) ((m3slot_t *) _sp + function->numArgSlots); memset (stack, 0x0, function->numLocalBytes); stack += function->numLocalBytes; @@ -252,7 +252,7 @@ d_m3OpDef (GetGlobal_s32) d_m3OpDef (GetGlobal_s64) { u64 * global = immediate (u64 *); - slot (u64) = * global; // printf ("get global: %p %" PRIi64 "\n", global, *global); + slot (u64) = * global; printf ("get global: %p %" PRIi64 "\n", global, *global); nextOp (); } diff --git a/source/m3_exec.h b/source/m3_exec.h index ebeb399..9edd338 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -875,7 +875,7 @@ d_m3Store_i (i64, i64) #undef m3MemCheck //--------------------------------------------------------------------------------------------------------------------- -# if d_m3EnableOptimizations +# if 0 //d_m3EnableOptimizations //--------------------------------------------------------------------------------------------------------------------- #define d_m3BinaryOpWith1_i(TYPE, NAME, OPERATION) \ diff --git a/source/m3_info.c b/source/m3_info.c index f4b8376..38c1f14 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -247,13 +247,18 @@ void DecodeOperation (char * o_string, u8 i_opcode, IM3Operation i_operation, switch (i_opcode) { - d_m3Decode (0xc0, Const) - d_m3Decode (0xc1, Entry) +// d_m3Decode (0xc0, Const) +// d_m3Decode (0xc1, Entry) d_m3Decode (c_waOp_call, Call) d_m3Decode (c_waOp_branch, Branch) d_m3Decode (c_waOp_branchTable, BranchTable) d_m3Decode (0x39, f64_Store) } + + #undef d_m3Decode + #define d_m3Decode(FUNC) if (i_operation == op_##FUNC) Decode_##FUNC (o_string, i_opcode, i_operation, i_opInfo, o_pc); + + d_m3Decode (Entry) } diff --git a/source/m3_parse.c b/source/m3_parse.c index 83418cc..517b107 100644 --- a/source/m3_parse.c +++ b/source/m3_parse.c @@ -126,9 +126,7 @@ M3Result ParseSection_Import (IM3Module io_module, bytes_t i_bytes, cbytes_t i { M3Result result = m3Err_none; - M3ImportInfo import, clearImport; - M3_INIT(import); - M3_INIT(clearImport); + M3ImportInfo import = { NULL, NULL }, clearImport = { NULL, NULL }; u32 numImports; _ (ReadLEB_u32 (& numImports, & i_bytes, i_end)); m3log (parse, "** Import [%d]", numImports); @@ -474,7 +472,7 @@ _ (Read_utf8 (& name, & i_bytes, i_end)); if (not io_module->functions [index].name) { io_module->functions [index].name = name; m3log (parse, "naming function [%d]: %s", index, name); - name = NULL; + name = NULL; // transfer ownership } // else m3log (parse, "prenamed: %s", io_module->functions [index].name); }