extensions
Steven Massey 4 years ago
parent fb70fab0f9
commit 533e1fcaea

@ -166,9 +166,8 @@ bool IsSlotAllocated (IM3Compilation o, u16 i_slot)
void MarkSlotAllocated (IM3Compilation o, u16 i_slot) void MarkSlotAllocated (IM3Compilation o, u16 i_slot)
{ d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated { d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated
o->m3Slots [i_slot] = 1; o->m3Slots [i_slot] = 1;
if (i_slot >= o->firstDynamicSlotIndex) // don't track constants o->maxAllocatedSlot = m3_max (o->maxAllocatedSlot, i_slot + 1);
o->numAllocatedSlots++;
} }
@ -236,10 +235,8 @@ void DeallocateSlot (IM3Compilation o, i16 i_slotIndex, u8 i_type)
d_m3Assert (o->m3Slots [i_slotIndex]); d_m3Assert (o->m3Slots [i_slotIndex]);
for (u16 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex) for (u16 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex)
{ {
if (-- o->m3Slots [i_slotIndex] == 0) -- o->m3Slots [i_slotIndex];
o->numAllocatedSlots--;
} }
} }
@ -280,22 +277,19 @@ u16 GetRegisterStackIndex (IM3Compilation o, u32 i_register)
u16 GetMaxUsedSlotPlusOne (IM3Compilation o) u16 GetMaxUsedSlotPlusOne (IM3Compilation o)
{ {
u16 i = o->firstDynamicSlotIndex; u16 slot = o->maxAllocatedSlot;
u32 allocated = o->numAllocatedSlots; while (slot > o->firstDynamicSlotIndex)
while (i < c_m3MaxFunctionSlots)
{ {
if (allocated == 0) o->maxAllocatedSlot = slot;
break;
if (IsSlotAllocated (o, i))
--allocated;
++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; u16 slot;
_ (AllocateSlots (o, & slot, i_type)); _ (AllocateSlots (o, & slot, i_type));
_ (Push (o, i_type, slot)); _ (Push (o, i_type, slot));
if (i_doEmit) if (i_doEmit)
EmitSlotOffset (o, slot); EmitSlotOffset (o, slot);
// printf ("push: %d\n", (u32) 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); u16 numRequiredSlots = GetTypeNumSlots (i_type);
// search for duplicate matching constant slot to reuse // 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)) 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) 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) for (u32 i = 0; i < numUsedConstSlots; ++i)
{ {
@ -1255,11 +1248,13 @@ _try {
_ (Pop (o)); _ (Pop (o));
u32 numArgs = i_type->numArgs; u32 numArgs = i_type->numArgs;
u16 argTop = topSlot + numArgs;
// args are 64-bit aligned
u16 argTop = topSlot + numArgs * 2;
while (numArgs--) while (numArgs--)
{ {
_ (CopyTopSlot (o, --argTop)); _ (CopyTopSlot (o, argTop -= 2));
_ (Pop (o)); _ (Pop (o));
} }
@ -2219,20 +2214,29 @@ M3Result Compile_Function (IM3Function io_function)
M3FuncType * ft = io_function->funcType; M3FuncType * ft = io_function->funcType;
// all args are 64-bit aligned // all args are 64-bit aligned
u32 argSlotCount = sizeof (u64) / sizeof (m3slot_t); const u32 argSlotCount = sizeof (u64) / sizeof (m3slot_t);
o->function->numArgSlots = GetFunctionNumArgs (o->function) * argSlotCount; 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]; u8 type = ft->argTypes [i];
_ (PushAllocatedSlot (o, type)); _ (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)); _ (CompileLocals (o));
o->firstDynamicSlotIndex = 0;
u16 maxSlot = GetMaxUsedSlotPlusOne (o); u16 maxSlot = GetMaxUsedSlotPlusOne (o);
o->function->numLocalBytes = (maxSlot - o->firstLocalSlotIndex) * sizeof (m3slot_t); o->function->numLocalBytes = (maxSlot - o->firstLocalSlotIndex) * sizeof (m3slot_t);
@ -2243,9 +2247,8 @@ _ (CompileLocals (o));
_ (Compile_ReserveConstants (o)); _ (Compile_ReserveConstants (o));
// start tracking the max stack used (Push() also updates this value) so that op_Entry can precisely detect stack overflow // 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); o->block.initStackIndex = o->firstDynamicStackIndex = o->stackIndex; m3log (compile, "start stack index: %d", (u32) o->firstDynamicStackIndex);
_ (EmitOp (o, op_Entry)); _ (EmitOp (o, op_Entry));

@ -101,7 +101,7 @@ typedef struct
// 'm3Slots' contains allocation usage counts // 'm3Slots' contains allocation usage counts
u8 m3Slots [c_m3MaxFunctionSlots]; u8 m3Slots [c_m3MaxFunctionSlots];
u16 numAllocatedSlots; u16 maxAllocatedSlot;
u16 regStackIndexPlusOne [2]; u16 regStackIndexPlusOne [2];

@ -121,12 +121,10 @@ M3Result m3Malloc (void ** o_ptr, size_t i_size)
return result; return result;
} }
void m3Free_impl (void * o_ptr) void m3Free_impl (void * i_ptr)
{ {
if (!o_ptr) return;
//printf("== free %p\n", o_ptr); //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) void * m3Realloc (void * i_ptr, size_t i_newSize, size_t i_oldSize)

@ -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 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); 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); void ReportError (IM3Runtime io_runtime, IM3Module i_module, IM3Function i_function, ccstr_t i_errorMessage, ccstr_t i_file, u32 i_lineNum);

@ -569,7 +569,7 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char
i_argc = 0; i_argc = 0;
IM3FuncType ftype = i_function->funcType; m3logif (runtime, PrintFuncTypeSignature (ftype)); 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) if (i_argc != ftype->numArgs)
_throw (m3Err_argumentCountMismatch); _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 // as this is used in spec tests
for (u32 i = 0; i < ftype->numArgs; ++i) for (u32 i = 0; i < ftype->numArgs; ++i)
{ {
m3slot_t * s = & stack[i]; u64 * s = & stack [i];
ccstr_t str = i_argv[i]; ccstr_t str = i_argv[i];
switch (ftype->argTypes[i]) { switch (ftype->argTypes[i]) {
@ -598,7 +598,7 @@ M3Result m3_CallWithArgs (IM3Function i_function, uint32_t i_argc, const char
} }
m3StackCheckInit(); 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 #if d_m3LogOutput
switch (ftype->returnType) { switch (ftype->returnType) {

@ -216,7 +216,7 @@ d_m3OpDef (Entry)
{ {
memcpy (stack, function->constants, function->numConstantBytes); memcpy (stack, function->constants, function->numConstantBytes);
} }
m3ret_t r = nextOpDirect (); m3ret_t r = nextOpDirect ();
# if d_m3LogExec # if d_m3LogExec

@ -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; 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, "(")); s += m3_max (0, snprintf (s, e-s, "("));
u64 * argSp = (u64 *) i_sp;
IM3FuncType funcType = i_function->funcType; IM3FuncType funcType = i_function->funcType;
if (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 += 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) if (i != numArgs - 1)
s += m3_max (0, snprintf (s, e-s, ", ")); s += m3_max (0, snprintf (s, e-s, ", "));

@ -8,7 +8,23 @@
#include "m3_env.h" #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) 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) 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; M3Result result = m3Err_none;
u32 index = io_module->numFunctions++; 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) 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); // 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; else result = m3Err_mallocFailed;

Loading…
Cancel
Save