another branch fix

extensions
Steven Massey 5 years ago
parent 278491e3bb
commit 630beb25ab

@ -488,8 +488,10 @@ M3Result AddTrapRecord (IM3Compilation o)
}
void PatchBranches (IM3Compilation o)
bool PatchBranches (IM3Compilation o)
{
bool patched = false;
M3CompilationScope * block = & o->block;
pc_t pc = GetPC (o);
@ -502,7 +504,11 @@ void PatchBranches (IM3Compilation o)
m3Free (block->patches);
block->patches = next;
patched = true;
}
return patched;
}
//-------------------------------------------------------------------------------------------------------------------------
@ -746,18 +752,36 @@ M3Result Compile_Else_End (IM3Compilation o, u8 i_opcode)
{
M3Result result = c_m3Err_none;
// function end:
// function end:
if (o->block.depth == 0)
{
PatchBranches (o);
if (o->block.type)
u8 valueType = o->block.type;
if (valueType)
{
// if (GetStackTopType (o) != c_m3Type_none)
// if there are branches to the function end, then their values are in a register
// if the block happens to have its top in a register too, then we can patch the branch
// to here. Otherwise, an ReturnStackTop is appended to the end of the function (at B) and
// branches patched there.
if (IsStackTopInRegister (o))
PatchBranches (o);
_ (ReturnStackTop (o));
}
_ (EmitOp (o, op_End));
else PatchBranches (o); // for no return type, branch to op_End
_ (EmitOp (o, op_Return));
// B: move register to return slot for branchehs
if (valueType)
{
if (PatchBranches (o))
{
PushRegister (o, valueType);
ReturnStackTop (o);
_ (EmitOp (o, op_Return));
}
}
}
_catch: return result;
@ -940,7 +964,7 @@ _ (MoveStackTopToRegister (o));
{
op = op_Branch;
if (scope->type != c_m3Type_none)
if (valueType != c_m3Type_none)
_ (MoveStackTopToRegister (o));
//_ (UnwindBlockStack (o));
@ -978,7 +1002,6 @@ _ (EnsureCodePageNumLines (o, numCodeLines));
_ (PreserveRegisterIfOccupied (o, c_m3Type_i64)); // move branch operand to a slot
u16 slot = GetStackTopSlotIndex (o);
_ (Pop (o));
// OPTZ: according to spec: "forward branches that target a control instruction with a non-empty
@ -1016,7 +1039,7 @@ _ (GetBlockScope (o, & scope, target));
_ (EmitOp (o, op_ContinueLoop));
EmitPointer (o, scope->pc);
ReleaseCompilationCodePage (o);
ReleaseCompilationCodePage (o); // FIX: continueOpPage can get lost if thrown
o->page = savedPage;
}
else _throw (c_m3Err_mallocFailedCodePage);
@ -1135,7 +1158,7 @@ _ (CompileCallArgsReturn (o, type, true));
_ (EmitOp (o, op_CallIndirect));
EmitPointer (o, o->module);
EmitPointer (o, type); // TODO: unify all types in M3Runtime
EmitPointer (o, type); // TODO: unify all types in M3Environment
EmitOffset (o, execTop);
EmitMemory (o);
}

@ -44,14 +44,14 @@ M3Result BridgeToNewPageIfNecessary (IM3Compilation o)
}
void log_emit (IM3Operation i_operation)
void log_emit (IM3Compilation o, IM3Operation i_operation)
{
# if DEBUG
OpInfo i = find_operation_info (i_operation);
if (i.info)
{
printf ("%s", i.info->name);
printf ("%p: %s", GetPC (o), i.info->name);
}
# endif
}
@ -72,7 +72,7 @@ M3Result EmitOp (IM3Compilation o, IM3Operation i_operation)
result = BridgeToNewPageIfNecessary (o);
if (not result)
{ m3logif (emit, log_emit (i_operation))
{ m3logif (emit, log_emit (o, i_operation))
EmitWord (o->page, i_operation);
}
}

@ -98,12 +98,13 @@ IM3Runtime m3_NewRuntime (IM3Environment i_environment, u32 i_stackSizeInBytes
if (env)
{
env->environment = i_environment;
m3Malloc (& env->stack, i_stackSizeInBytes);
if (env->stack)
{
env->numStackSlots = i_stackSizeInBytes / sizeof (m3reg_t);
env->environment = i_environment;
}
else m3Free (env);
}
@ -656,9 +657,16 @@ _ ((M3Result)Call (i_function->compiled, stack, linearMemory, d_m3OpDefaul
IM3CodePage AcquireCodePage (IM3Runtime i_runtime)
{
if (i_runtime->pagesOpen)
{
return PopCodePage (& i_runtime->pagesOpen);
}
else
{
if (i_runtime->environment)
i_runtime->environment->numCodePages++;
return NewCodePage (500); // for 4kB page
}
}
@ -684,16 +692,25 @@ IM3CodePage AcquireCodePageWithCapacity (IM3Runtime i_runtime, u32 i_lineCount
}
u32 CountPages (IM3CodePage i_page)
{
u32 numPages = 0;
while (i_page)
{
++numPages;
i_page = i_page->info.next;
}
return numPages;
}
void ReleaseCodePage (IM3Runtime i_runtime, IM3CodePage i_codePage)
{
if (i_codePage)
{
# if defined (DEBUG)
# if d_m3LogCodePages
dump_code_page (i_codePage, /* startPC: */ NULL);
# endif
# endif
IM3CodePage * list;
if (NumFreeLines (i_codePage) < c_m3CodePageFreeLinesThreshold)
@ -702,6 +719,22 @@ void ReleaseCodePage (IM3Runtime i_runtime, IM3CodePage i_codePage)
list = & i_runtime->pagesOpen;
PushCodePage (list, i_codePage);
# if defined (DEBUG)
u32 numOpen = CountPages (i_runtime->pagesOpen);
u32 numFull = CountPages (i_runtime->pagesFull);
u32 numTotal = i_runtime->environment ? i_runtime->environment->numCodePages : numFull + numOpen;
m3log (code, "open-pages: %d; full-pages: %d; total: %d", numOpen, numFull, numTotal);
// d_m3Assert (numOpen + numFull == numTotal);
# if d_m3LogCodePages
dump_code_page (i_codePage, /* startPC: */ NULL);
# endif
# endif
}
}

@ -187,6 +187,7 @@ IM3Function Module_GetFunction (IM3Module i_module, u32
//---------------------------------------------------------------------------------------------------------------------------------
typedef struct M3Environment
{
u32 numCodePages;
// u32 numFuncTypes;
// M3FuncType * funcTypes;
}

@ -445,10 +445,10 @@ else:
"unreachable",
"switch", "if", "br", "br_if", "br_table", "loop", "block",
"return", "nop", "start",
"return", "nop", "start", "unwind"
#--- TODO ---
#"labels", "unwind",
#"labels",
#"float_exprs",
]))

Loading…
Cancel
Save