m_bit exec = back->opcode;
m_uint val = back->m_val;
m_uint val2 = back->m_val2;
- back->opcode = eRegPushMem;
- back->m_val = back->m_val2 = 0;
+ back->opcode = eReg2Reg;
+ back->m_val2 = -SZ_INT;
+ regpush(emit, SZ_INT);
const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
instr->m_val = val;
instr->m_val2 = val2;
ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
const Func f = sp->exp->d.exp_call.m_func;
if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+ regpush(emit, SZ_INT*2);
+ // (re-)emit owner
+ if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
+ emit_exp(emit, sp->exp->d.exp_call.func->d.exp_dot.base);
+ else {
+ assert(sp->exp->d.exp_call.func->exp_type == ae_exp_primary);
+ emit_add_instr(emit, RegPushMem);
+ }
+ regpop(emit, SZ_INT*3);
const m_uint depth = f->def->stack_depth;
regpop(emit, depth -SZ_INT);
const Instr spork = emit_add_instr(emit, SporkMemberFptr);
ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, const m_uint status) {
regpushi(emit, status);
CHECK_BB(emit_exp(emit, stmt->exp))
- emit_add_instr(emit, SetObj);
const Instr member = emit_add_instr(emit, DotMember4);
member->m_val = SZ_INT;
emit_add_instr(emit, int_r_assign);
emit_add_instr(emit, GWOP_EXCEPT);
for(m_uint i = 0; i < depth - 1; ++i) {
const Instr access = emit_add_instr(emit, ArrayAccess);
- access->m_val = i;
+ access->m_val = i * SZ_INT;
+ access->m_val2 = !i ? SZ_INT : 0;
const Instr get = emit_add_instr(emit, ArrayGet);
- get->m_val = i;
+ get->m_val = i * SZ_INT;
get->m_val2 = -SZ_INT;
emit_add_instr(emit, GWOP_EXCEPT);
}
const Instr post_pop = emit_add_instr(emit, RegPop);
post_pop->m_val = SZ_INT;
const Instr access = emit_add_instr(emit, ArrayAccess);
- access->m_val = depth;
+ access->m_val = depth * SZ_INT;
}
ANN static void array_finish(const Emitter emit, const m_uint depth,
const m_uint size, const m_bool is_var) {
const Instr get = emit_add_instr(emit, is_var ? ArrayAddr : ArrayGet);
- get->m_val = depth;
+ get->m_val = depth * SZ_INT;
const Instr push = emit_add_instr(emit, ArrayValid);
push->m_val = is_var ? SZ_INT : size;
}
&&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
&&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
&&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref,
- &&setobj, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
+ &&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
&&staticint, &&staticfloat, &&staticother,
&&dotfunc, &&dotstaticfunc,
&&gcini, &&gcadd, &&gcend,
DISPATCH()
PRAGMA_POP()
sporkmemberfptr:
- for(m_uint i = 0; i < VAL; i+= SZ_INT)
+ for(m_uint i = SZ_INT; i < VAL; i+= SZ_INT)
*(m_uint*)(child->reg + i) = *(m_uint*)(reg - VAL + i);
- *(M_Object*)(child->reg + VAL) = a.obj;
+ *(M_Object*)(child->reg + VAL) = *(M_Object*)(reg + VAL + SZ_INT);
*(m_uint*)(child->reg + VAL + SZ_INT) = *(m_uint*)(reg + VAL - SZ_INT*2);
child->reg += VAL + SZ_INT*2;
DISPATCH()
goto _goto;
arrayaccess:
{
- register const m_int idx = *(m_int*)(reg + SZ_INT * VAL);
+ register const m_int idx = *(m_int*)(reg + VAL);
+ a.obj = *(M_Object*)(reg-VAL2);
if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
gw_err(_(" ... at index [%" INT_F "]\n"), idx);
gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL);
DISPATCH()
}
arrayget:
- m_vector_get(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL), (reg + (m_int)VAL2));
+ m_vector_get(ARRAY(a.obj), *(m_int*)(reg + VAL), (reg + (m_int)VAL2));
DISPATCH()
arrayaddr:
- *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + SZ_INT * VAL));
+ *(m_bit**)(reg + (m_int)VAL2) = m_vector_addr(ARRAY(a.obj), *(m_int*)(reg + VAL));
DISPATCH()
arrayvalid:
// are we sure it is the array ?
reg += SZ_INT;
DISPATCH()
addref:
- a.obj = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2);
- goto addrefcommon;
+ {
+ const M_Object o = *((M_Object*)(reg+(m_int)VAL) + (m_int)VAL2);
+ if(o)
+ ++o->ref;
+ }
+ DISPATCH()
addrefaddr:
- a.obj = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2);
-addrefcommon:
- if(a.obj)
- ++a.obj->ref;
+ {
+ const M_Object o = *(*(M_Object**)(reg+(m_int)VAL) + (m_int)VAL2);
+ if(o)
+ ++o->ref;
+ }
DISPATCH()
objassign:
- a.obj = **(M_Object**)(reg -SZ_INT);
- if(a.obj) {
- --a.obj->ref;
- _release(a.obj, shred);
+{
+ const M_Object o = **(M_Object**)(reg -SZ_INT);
+ if(o) {
+ --o->ref;
+ _release(o, shred);
}
+}
assign:
reg -= SZ_INT;
**(M_Object**)reg = *(M_Object*)(reg-SZ_INT);
remref:
release(*(M_Object*)(mem + VAL), shred);
DISPATCH()
-setobj:
- a.obj = *(M_Object*)(reg-SZ_INT-(m_int)VAL);
- DISPATCH();
except:
/* TODO: Refactor except instruction *
* so that *
* VAL = offset (no default SZ_INT) *
* VAL2 = error message *
* grep for GWOP_EXCEPT and Except, exception... */
- if(!(a.obj = *(M_Object*)(reg-SZ_INT-VAL))) {
+ if(!*(M_Object*)(reg-SZ_INT-VAL)) {
shred->pc = PC;
exception(shred, "NullPtrException");
continue;
}
DISPATCH();
allocmemberaddr:
- a.obj = *(M_Object*)mem;
- *(m_bit**)reg = a.obj->data + VAL;
+ *(m_bit**)reg = (*(M_Object*)mem)->data + VAL;
reg += SZ_INT;
DISPATCH()
dotmember:
- *(m_uint*)(reg-SZ_INT) = *(m_uint*)(a.obj->data + VAL);
+ *(m_uint*)(reg-SZ_INT) = *(m_uint*)((*(M_Object*)(reg-SZ_INT))->data + VAL);
DISPATCH()
dotfloat:
- *(m_float*)(reg-SZ_INT) = *(m_float*)(a.obj->data + VAL);
+ *(m_float*)(reg-SZ_INT) = *(m_float*)((*(M_Object*)(reg-SZ_INT))->data + VAL);
reg += SZ_FLOAT - SZ_INT;
DISPATCH()
dotother:
// LOOP_OPTIM
PRAGMA_PUSH()
for(m_uint i = 0; i <= VAL2; i += SZ_INT)
- *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)((a.obj->data + VAL) + i);
+ *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)(((*(M_Object*)(reg-SZ_INT))->data + VAL) + i);
PRAGMA_POP()
reg += VAL2 - SZ_INT;
DISPATCH()
dotaddr:
- *(m_bit**)(reg-SZ_INT) = (a.obj->data + VAL);
+ *(m_bit**)(reg-SZ_INT) = ((*(M_Object*)(reg-SZ_INT))->data + VAL);
DISPATCH()
staticint:
*(m_uint*)reg = *(m_uint*)VAL;
reg += VAL2;
DISPATCH()
dotfunc:
- assert(a.obj);
reg += SZ_INT;
+ VAL2 = SZ_INT;
dotstaticfunc:
PRAGMA_PUSH()
- *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code;
+ *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at((*(M_Object*)(reg-SZ_INT-VAL2))->vtable, VAL))->code;
PRAGMA_POP()
DISPATCH()
gcini:
vector_add(&shred->gc, *(vtype*)(reg-SZ_INT));
DISPATCH();
gcend:
- while((a.obj = (M_Object)vector_pop(&shred->gc)))
- _release(a.obj, shred);
+{
+ M_Object o;
+ while((o = (M_Object)vector_pop(&shred->gc)))
+ _release(o, shred);
+}
DISPATCH()
gacktype:
{
const M_Object o = *(M_Object*)(reg - SZ_INT);
if(o)
*(Type*)reg = o->type_ref;
- DISPATCH()
}
+ DISPATCH()
gackend:
{
m_str str = *(m_str*)(reg - SZ_INT);