From 533e1fcaeaac22c58d6eac8780e926e7b9ae4d33 Mon Sep 17 00:00:00 2001 From: Steven Massey Date: Mon, 24 Feb 2020 16:51:49 -0800 Subject: [PATCH] issue #5 work --- source/m3_compile.c | 79 +++++++++++++++++++++++---------------------- source/m3_compile.h | 2 +- source/m3_core.c | 6 ++-- source/m3_core.h | 2 +- source/m3_env.c | 6 ++-- source/m3_exec.c | 2 +- source/m3_info.c | 6 ++-- source/m3_module.c | 36 +++++++++++---------- 8 files changed, 72 insertions(+), 67 deletions(-) diff --git a/source/m3_compile.c b/source/m3_compile.c index a5a4505..e288247 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -166,9 +166,8 @@ bool IsSlotAllocated (IM3Compilation o, 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; - - if (i_slot >= o->firstDynamicSlotIndex) // don't track constants - o->numAllocatedSlots++; + + o->maxAllocatedSlot = m3_max (o->maxAllocatedSlot, i_slot + 1); } @@ -236,10 +235,8 @@ void DeallocateSlot (IM3Compilation o, i16 i_slotIndex, u8 i_type) d_m3Assert (o->m3Slots [i_slotIndex]); for (u16 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex) { - if (-- o->m3Slots [i_slotIndex] == 0) - o->numAllocatedSlots--; + -- o->m3Slots [i_slotIndex]; } - } @@ -280,22 +277,19 @@ u16 GetRegisterStackIndex (IM3Compilation o, u32 i_register) u16 GetMaxUsedSlotPlusOne (IM3Compilation o) { - u16 i = o->firstDynamicSlotIndex; + u16 slot = o->maxAllocatedSlot; - u32 allocated = o->numAllocatedSlots; - - while (i < c_m3MaxFunctionSlots) + while (slot > o->firstDynamicSlotIndex) { - if (allocated == 0) - break; - - if (IsSlotAllocated (o, i)) - --allocated; + o->maxAllocatedSlot = slot; - ++i; + if (IsSlotAllocated (o, slot - 1)) + break; + + --slot; } - - return i; + + return slot; } @@ -463,10 +457,10 @@ M3Result _PushAllocatedSlotAndEmit (IM3Compilation o, u8 i_type, bool i_doEmit u16 slot; _ (AllocateSlots (o, & slot, i_type)); -_ (Push (o, i_type, slot)); +_ (Push (o, i_type, slot)); - if (i_doEmit) - EmitSlotOffset (o, slot); + if (i_doEmit) + EmitSlotOffset (o, slot); // printf ("push: %d\n", (u32) slot); @@ -496,17 +490,16 @@ M3Result PushConst (IM3Compilation o, u64 i_word, u8 i_type) u16 numRequiredSlots = GetTypeNumSlots (i_type); // search for duplicate matching constant slot to reuse - if (numRequiredSlots == 2) + if (numRequiredSlots == 2 and numUsedConstSlots >= 2) { - numUsedConstSlots &= ~1; // round down to even num + u16 firstConstSlot = o->firstConstSlotIndex; + AlignSlotIndexToType (& firstConstSlot, c_m3Type_i64); - for (u32 i = 0; i < numUsedConstSlots; i += 2) + for (u32 slot = firstConstSlot; slot < o->maxConstSlotIndex - 1; slot += 2) { - u16 slot = o->firstConstSlotIndex + i; - if (IsSlotAllocated (o, slot) and IsSlotAllocated (o, slot + 1)) { - u64 * constant = (u64 *) & o->constants [i]; + u64 * constant = (u64 *) & o->constants [slot - o->firstConstSlotIndex]; if (* constant == i_word) { @@ -517,7 +510,7 @@ _ (Push (o, i_type, slot)); } } } - else + else if (numRequiredSlots == 1) { for (u32 i = 0; i < numUsedConstSlots; ++i) { @@ -1255,11 +1248,13 @@ _try { _ (Pop (o)); u32 numArgs = i_type->numArgs; - u16 argTop = topSlot + numArgs; + + // args are 64-bit aligned + u16 argTop = topSlot + numArgs * 2; while (numArgs--) { -_ (CopyTopSlot (o, --argTop)); +_ (CopyTopSlot (o, argTop -= 2)); _ (Pop (o)); } @@ -2219,20 +2214,29 @@ M3Result Compile_Function (IM3Function io_function) M3FuncType * ft = io_function->funcType; // all args are 64-bit aligned - u32 argSlotCount = sizeof (u64) / sizeof (m3slot_t); - o->function->numArgSlots = GetFunctionNumArgs (o->function) * argSlotCount; + const u32 argSlotCount = sizeof (u64) / sizeof (m3slot_t); + u32 numArgs = GetFunctionNumArgs (o->function); - for (u32 i = 0; i < GetFunctionNumArgs (io_function); ++i) + for (u32 i = 0; i < numArgs; ++i) { u8 type = ft->argTypes [i]; _ (PushAllocatedSlot (o, type)); - o->firstDynamicSlotIndex += argSlotCount; // don't let the allocator fill-in + + if (i < numArgs - 1) + { + // prevent allocator fill-in + o->firstDynamicSlotIndex += argSlotCount; + } + else + { + // final arg only allocates its natural width + o->firstDynamicSlotIndex += GetTypeNumSlots (type); + } } - o->firstLocalSlotIndex = o->firstDynamicSlotIndex; + o->function->numArgSlots = o->firstLocalSlotIndex = o->firstDynamicSlotIndex; _ (CompileLocals (o)); - o->firstDynamicSlotIndex = 0; u16 maxSlot = GetMaxUsedSlotPlusOne (o); o->function->numLocalBytes = (maxSlot - o->firstLocalSlotIndex) * sizeof (m3slot_t); @@ -2243,9 +2247,8 @@ _ (CompileLocals (o)); _ (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->firstDynamicSlotIndex; + o->function->maxStackSlots = o->maxAllocatedSlot = o->firstDynamicSlotIndex; - o->numAllocatedSlots = 0; // this var only tracks dynamic slots so clear local+constant allocations o->block.initStackIndex = o->firstDynamicStackIndex = o->stackIndex; m3log (compile, "start stack index: %d", (u32) o->firstDynamicStackIndex); _ (EmitOp (o, op_Entry)); diff --git a/source/m3_compile.h b/source/m3_compile.h index dff9133..2421e65 100644 --- a/source/m3_compile.h +++ b/source/m3_compile.h @@ -101,7 +101,7 @@ typedef struct // 'm3Slots' contains allocation usage counts u8 m3Slots [c_m3MaxFunctionSlots]; - u16 numAllocatedSlots; + u16 maxAllocatedSlot; u16 regStackIndexPlusOne [2]; diff --git a/source/m3_core.c b/source/m3_core.c index 04db810..3c984bd 100644 --- a/source/m3_core.c +++ b/source/m3_core.c @@ -121,12 +121,10 @@ M3Result m3Malloc (void ** o_ptr, size_t i_size) return result; } -void m3Free_impl (void * o_ptr) +void m3Free_impl (void * i_ptr) { - if (!o_ptr) return; - //printf("== free %p\n", o_ptr); - free(o_ptr); + free (i_ptr); } void * m3Realloc (void * i_ptr, size_t i_newSize, size_t i_oldSize) diff --git a/source/m3_core.h b/source/m3_core.h index 3c80416..a8bff25 100644 --- a/source/m3_core.h +++ b/source/m3_core.h @@ -228,7 +228,7 @@ M3Result ReadLEB_i32 (i32 * o_value, bytes_t * io_bytes, cbytes_t M3Result ReadLEB_i64 (i64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_utf8 (cstr_t * o_utf8, bytes_t * io_bytes, cbytes_t i_end); -size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type); +size_t SPrintArg (char * o_string, size_t i_n, u64 * i_sp, u8 i_type); void ReportError (IM3Runtime io_runtime, IM3Module i_module, IM3Function i_function, ccstr_t i_errorMessage, ccstr_t i_file, u32 i_lineNum); diff --git a/source/m3_env.c b/source/m3_env.c index 56f99d2..3a9ec13 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -569,7 +569,7 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char i_argc = 0; IM3FuncType ftype = i_function->funcType; m3logif (runtime, PrintFuncTypeSignature (ftype)); - m3stack_t stack = (m3stack_t) runtime->stack; + u64 * stack = (u64 *) runtime->stack; if (i_argc != ftype->numArgs) _throw (m3Err_argumentCountMismatch); @@ -578,7 +578,7 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char // as this is used in spec tests for (u32 i = 0; i < ftype->numArgs; ++i) { - m3slot_t * s = & stack[i]; + u64 * s = & stack [i]; ccstr_t str = i_argv[i]; switch (ftype->argTypes[i]) { @@ -598,7 +598,7 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char } m3StackCheckInit(); -_ ((M3Result)Call (i_function->compiled, stack, runtime->memory.mallocated, d_m3OpDefaultArgs)); +_ ((M3Result) Call (i_function->compiled, stack, runtime->memory.mallocated, d_m3OpDefaultArgs)); #if d_m3LogOutput switch (ftype->returnType) { diff --git a/source/m3_exec.c b/source/m3_exec.c index cfec6a3..cd1cf0c 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -216,7 +216,7 @@ d_m3OpDef (Entry) { memcpy (stack, function->constants, function->numConstantBytes); } - + m3ret_t r = nextOpDirect (); # if d_m3LogExec diff --git a/source/m3_info.c b/source/m3_info.c index e077ad8..f4b8376 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -77,7 +77,7 @@ void PrintFuncTypeSignature (IM3FuncType i_funcType) } -size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type) +size_t SPrintArg (char * o_string, size_t i_n, u64 * i_sp, u8 i_type) { int len = 0; @@ -107,6 +107,8 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp) s += m3_max (0, snprintf (s, e-s, "(")); + u64 * argSp = (u64 *) i_sp; + IM3FuncType funcType = i_function->funcType; if (funcType) { @@ -119,7 +121,7 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp) s += m3_max (0, snprintf (s, e-s, "%s: ", c_waTypes [type])); - s += SPrintArg (s, e-s, i_sp + i, type); + s += SPrintArg (s, e-s, argSp + i, type); if (i != numArgs - 1) s += m3_max (0, snprintf (s, e-s, ", ")); diff --git a/source/m3_module.c b/source/m3_module.c index 3ca3ae1..3ace03f 100644 --- a/source/m3_module.c +++ b/source/m3_module.c @@ -8,7 +8,23 @@ #include "m3_env.h" -static void Module_FreeFunctions(IM3Module i_module); + +void Module_FreeFunctions (IM3Module i_module) +{ + for (u32 i = 0; i < i_module->numFunctions; ++i) + { + IM3Function func = &i_module->functions [i]; + m3Free (func->constants); + + if (func->name != func->import.fieldUtf8) + { + m3Free (func->name); + } + + FreeImportInfo (& func->import); + } +} + void m3_FreeModule (IM3Module i_module) { @@ -32,20 +48,6 @@ void m3_FreeModule (IM3Module i_module) } } -static void Module_FreeFunctions(IM3Module i_module) -{ - for (u32 i = 0; i < i_module->numFunctions; ++i) - { - IM3Function func = &i_module->functions[i]; - m3Free (func->constants); - if (func->name != func->import.fieldUtf8) - { - m3Free (func->name); - } - - FreeImportInfo (&func->import); - } -} M3Result Module_AddGlobal (IM3Module io_module, IM3Global * o_global, u8 i_type, bool i_mutable, bool i_isImported) { @@ -76,7 +78,7 @@ M3Result Module_AddFunction (IM3Module io_module, u32 i_typeIndex, IM3ImportIn M3Result result = m3Err_none; u32 index = io_module->numFunctions++; - io_module->functions = (M3Function*)m3ReallocArray (io_module->functions, M3Function, io_module->numFunctions, index); + io_module->functions = (M3Function *) m3ReallocArray (io_module->functions, M3Function, io_module->numFunctions, index); if (io_module->functions) { @@ -95,7 +97,7 @@ M3Result Module_AddFunction (IM3Module io_module, u32 i_typeIndex, IM3ImportIn // m3log (module, " added function: %3d; sig: %d", index, i_typeIndex); } - else result = "unknown type sig index"; + else result = "type sig index out of bounds"; } else result = m3Err_mallocFailed;