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)
{ 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));

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

@ -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)

@ -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);

@ -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) {

@ -216,7 +216,7 @@ d_m3OpDef (Entry)
{
memcpy (stack, function->constants, function->numConstantBytes);
}
m3ret_t r = nextOpDirect ();
# 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;
@ -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, ", "));

@ -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;

Loading…
Cancel
Save