|
|
|
@ -48,7 +48,7 @@ u32 GetTypeNumSlots (u8 i_type)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i16 GetStackTopIndex (IM3Compilation o)
|
|
|
|
|
{
|
|
|
|
|
{ d_m3Assert (o->stackIndex > 0);
|
|
|
|
|
return o->stackIndex - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -100,13 +100,19 @@ i16 GetNumBlockValues (IM3Compilation o)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IsStackIndexInRegister (IM3Compilation o, u16 i_stackIndex)
|
|
|
|
|
{ d_m3Assert (i_stackIndex < o->stackIndex);
|
|
|
|
|
return (o->wasmStack [i_stackIndex] >= d_m3Reg0SlotAlias);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool IsStackTopInRegister (IM3Compilation o)
|
|
|
|
|
{
|
|
|
|
|
i16 i = GetStackTopIndex (o); d_m3Assert (i >= 0 or IsStackPolymorphic (o));
|
|
|
|
|
i16 i = GetStackTopIndex (o); d_m3Assert (i >= 0 or IsStackPolymorphic (o));
|
|
|
|
|
|
|
|
|
|
if (i >= 0)
|
|
|
|
|
{
|
|
|
|
|
return (o->wasmStack [i] >= d_m3Reg0SlotAlias);
|
|
|
|
|
return IsStackIndexInRegister (o, (u16) i);
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
}
|
|
|
|
@ -143,7 +149,7 @@ bool IsStackTopMinus1InRegister (IM3Compilation o)
|
|
|
|
|
{
|
|
|
|
|
i16 i = GetStackTopIndex (o);
|
|
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
|
if (i >= 1)
|
|
|
|
|
{
|
|
|
|
|
return (o->wasmStack [i - 1] >= d_m3Reg0SlotAlias);
|
|
|
|
|
}
|
|
|
|
@ -570,15 +576,16 @@ bool PatchBranches (IM3Compilation o)
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
M3Result CopyTopSlot (IM3Compilation o, u16 i_destSlot)
|
|
|
|
|
M3Result CopyStackSlot (IM3Compilation o, u16 i_stackIndex, u16 i_destSlot)
|
|
|
|
|
{
|
|
|
|
|
M3Result result = m3Err_none;
|
|
|
|
|
|
|
|
|
|
IM3Operation op;
|
|
|
|
|
|
|
|
|
|
u8 type = GetStackTopType (o);
|
|
|
|
|
u8 type = GetStackBottomType (o, i_stackIndex);
|
|
|
|
|
bool inRegister = IsStackIndexInRegister (o, i_stackIndex);
|
|
|
|
|
|
|
|
|
|
if (IsStackTopInRegister (o))
|
|
|
|
|
if (inRegister)
|
|
|
|
|
{
|
|
|
|
|
op = c_setSetOps [type];
|
|
|
|
|
}
|
|
|
|
@ -587,13 +594,24 @@ M3Result CopyTopSlot (IM3Compilation o, u16 i_destSlot)
|
|
|
|
|
_ (EmitOp (o, op));
|
|
|
|
|
EmitSlotOffset (o, i_destSlot);
|
|
|
|
|
|
|
|
|
|
if (IsStackTopInSlot (o))
|
|
|
|
|
EmitSlotOffset (o, GetStackTopSlotIndex (o));
|
|
|
|
|
if (not inRegister)
|
|
|
|
|
EmitSlotOffset (o, o->wasmStack [i_stackIndex]);
|
|
|
|
|
|
|
|
|
|
_catch: return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
M3Result CopyTopSlot (IM3Compilation o, u16 i_destSlot)
|
|
|
|
|
{
|
|
|
|
|
M3Result result;
|
|
|
|
|
|
|
|
|
|
i16 stackTop = GetStackTopIndex (o);
|
|
|
|
|
_ (CopyStackSlot (o, (u16) stackTop, i_destSlot));
|
|
|
|
|
|
|
|
|
|
_catch: return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// a copy-on-write strategy is used with locals. when a get local occurs, it's not copied anywhere. the stack
|
|
|
|
|
// entry just has a index pointer to that local memory slot.
|
|
|
|
|
// then, when a previously referenced local is set, the current value needs to be preserved for those references
|
|
|
|
|