eRegPushBase4,
eRegDup,
eRegDup2,
+ eRegDup3,
eMemSetImm,
eRegPushMe,
eRegPushMaybe,
eBranchNeqInt,
eBranchEqFloat,
eBranchNeqFloat,
- eDecIntAddr,
- eInitLoopCounter,
eArrayAppend,
eArrayTop,
eObjectInstantiate,
#define RegPushBase4 (f_instr)eRegPushBase4
#define RegDup (f_instr)eRegDup
#define RegDup2 (f_instr)eRegDup2
+#define RegDup3 (f_instr)eRegDup3
#define MemSetImm (f_instr)eMemSetImm
#define RegPushMe (f_instr)eRegPushMe
#define RegPushMaybe (f_instr)eRegPushMaybe
#define BranchNeqInt (f_instr)eBranchNeqInt
#define BranchEqFloat (f_instr)eBranchEqFloat
#define BranchNeqFloat (f_instr)eBranchNeqFloat
-#define DecIntAddr (f_instr)eDecIntAddr
-#define InitLoopCounter (f_instr)eInitLoopCounter
#define ArrayAppend (f_instr)eArrayAppend
#define ArrayTop (f_instr)eArrayTop
#define ObjectInstantiate (f_instr)eObjectInstantiate
RegPushBase4
RegDup
RegDup2
+RegDup3
MemSetImm
RegPushMe
RegPushMaybe
BranchNeqInt
BranchEqFloat
BranchNeqFloat
-DecIntAddr
-InitLoopCounter
ArrayAppend
ArrayTop
ObjectInstantiate
ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) { GWDEBUG_EXE
emit_push_stack(emit);
CHECK_BB(emit_exp(emit, stmt->cond, 0))
- m_int* counter = (m_int*)xcalloc(1, SZ_INT);
- const Instr init = emit_add_instr(emit, InitLoopCounter);
- init->m_val = (m_uint)counter;
const m_uint index = emit_code_size(emit);
- const Instr deref = emit_add_instr(emit, DotStatic);
- deref->m_val = (m_uint)counter;
- deref->m_val2 = SZ_INT;
+ emit_add_instr(emit, RegDup3);
+ emit_add_instr(emit, int_post_dec);
const Instr op = emit_add_instr(emit, BranchEqInt);
- const Instr dec = emit_add_instr(emit, DecIntAddr);
- dec->m_val = (m_uint)counter;
CHECK_BB(scoped_stmt(emit, stmt->body, 1))
const Instr _goto = emit_add_instr(emit, Goto);
_goto->m_val = index;
op->m_val = emit_code_size(emit);
+ const Instr pop = emit_add_instr(emit, RegPop);
+ pop->m_val = SZ_INT;
emit_pop_stack(emit, index);
return GW_OK;
}
&®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr,
&&pushnow,
&&baseint, &&basefloat, &&baseother, &&baseaddr,
- &®dup, &®dup2,
+ &®dup, &®dup2, &®dup3,
&&memsetimm,
&®pushme, &®pushmaybe,
&&funcreturn,
&&funcusr, &®pop, &®tomem, &&overflow, &&next, &&funcusrend, &&funcmemberend,
&&sporkini, &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&forkend, &&sporkend,
&&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
- &&decintaddr, &&initloop,
&&arrayappend, &&arraytop, &&newobj,
&&addref, &&assign, &&remref,
&&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
*(m_uint*)(reg+SZ_INT) = *(m_uint*)(reg);
reg += SZ_INT;
DISPATCH()
+regdup3:
+ *(m_uint**)reg = &*(m_uint*)(reg-SZ_INT);
+ reg += SZ_INT;
+ DISPATCH()
memsetimm:
*(m_uint*)(mem+instr->m_val) = instr->m_val2;
DISPATCH();
if(*(m_float*)reg)
pc = instr->m_val;
DISPATCH();
-decintaddr:
- --(*((m_uint*)(instr->m_val)));
- DISPATCH()
-initloop:
- reg -= SZ_INT;
- (*(m_uint*)instr->m_val) = labs(*(m_int*)reg);
- DISPATCH()
arrayappend:
m_vector_add(ARRAY(a.obj), reg);
release(a.obj, shred);
else if(instr->execute == SwitchIni) {
free_vector((Vector)instr->m_val);
free_map((Map)instr->m_val2);
- } else if(instr->opcode == eInitLoopCounter)
- free((m_int*)instr->m_val);
- else if(instr->execute == VarargIni) {
+ } else if(instr->execute == VarargIni) {
if(instr->m_val2)
free_vector((Vector)instr->m_val2);
}