.flag = tflag_emit};
return envset_run(&es, t);
}
-/*
-ANN static inline m_uint emit_code_size(const Emitter emit) {
- return vector_size(&emit->code->instr);
-}
-*/
+
ANN static void emit_struct_dtor(const Emitter emit, const Type type,
const m_uint offset) {
+ const m_uint code_offset = emit_code_offset(emit);
emit->code->frame->curr_offset += SZ_INT;
- const Instr instr = emit_add_instr(emit, RegPushMem4);
- instr->m_val = offset;
- const Instr tomem = emit_add_instr(emit, Reg2Mem);
- tomem->m_val = emit->code->frame->curr_offset;
- tomem->m_val2 = -SZ_INT;
+ emit_regpushmem4(emit, offset, 0);
+ emit_regtomem(emit, code_offset, -SZ_INT);
emit_pushimm(emit, (m_uint)type);
- const Instr tomem2 = emit_add_instr(emit, Reg2Mem);
- tomem2->m_val = emit->code->frame->curr_offset + SZ_INT;
- tomem2->m_val2 = -SZ_INT;
+ emit_regtomem(emit, code_offset + SZ_INT, -SZ_INT);
emit_setimm(emit, (m_uint)type->nspc->dtor, SZ_INT);
- const m_uint code_offset = emit_code_offset(emit);
emit_setimm(emit, code_offset, SZ_INT*2);
emit_regmove(emit, SZ_INT * 2);
const Instr prelude = emit_add_instr(emit, SetCode);
emit->code->frame->curr_offset -= SZ_INT;
}
-ANN static void struct_pop(const Emitter emit, const Type type,
- const m_uint offset) {
+ANN void emit_object_release(const Emitter emit, const m_uint offset) {
+ const Instr instr = emit_add_instr(emit, ObjectRelease);
+ instr->m_val = offset;
+}
+
+ANN void emit_compound_release(const Emitter emit, const Type t, const m_uint offset) {
+ if(isa(t, emit->gwion->type[et_compound]) > 0)
+ return emit_object_release(emit, offset);
+ emit_struct_release(emit, t, offset);
+}
+
+ANN void emit_struct_release(const Emitter emit, const Type type,
+ const m_uint offset) {
if (!type->info->tuple) return;
if (type->nspc->dtor) emit_struct_dtor(emit, type, offset);
- for (m_uint i = 0; i < vector_size(&type->info->tuple->types); ++i) {
- const Type t = (Type)vector_at(&type->info->tuple->types, i);
- if (isa(t, emit->gwion->type[et_object]) > 0) {
- const Instr instr = emit_add_instr(emit, ObjectRelease);
- instr->m_val = offset + vector_at(&type->info->tuple->offset, i);
- } else if (tflag(t, tflag_struct))
- struct_pop(emit, t, offset + vector_at(&type->info->tuple->offset, i));
+ const Vector v = &type->info->tuple->types;
+ for (m_uint i = 0; i < vector_size(v); i++) {
+ const Type t = (Type)vector_at(v, i);
+ if (isa(t, emit->gwion->type[et_compound]) > 0)
+ emit_compound_release(emit, t, offset + vector_at(&type->info->tuple->offset, i));
}
}
ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt);
ANN static m_bool emit_defers(const Emitter emit) {
- if (!vector_size(&emit->code->frame->defer)) return GW_OK;
- Stmt stmt;
- while ((stmt = (Stmt)vector_pop(&emit->code->frame->defer)))
- CHECK_BB(emit_stmt(emit, stmt));
+ const Vector v = &emit->code->frame->defer;
+ if (!vector_size(v)) return GW_OK;
+ m_uint i;
+ for(i = vector_size(v) + 1; --i;) {
+ const Stmt s = (Stmt)vector_at(v, i - 1);
+ if(s) CHECK_BB(emit_stmt(emit, s));
+ }
+ VLEN(v) = i;
+ vector_realloc(v);
return GW_OK;
}
ANN static m_bool emit_defers2(const Emitter emit) {
- for (m_uint i = vector_size(&emit->code->frame->defer) + 1; --i;) {
- const Stmt stmt = (Stmt)vector_at(&emit->code->frame->defer, i - 1);
- if (!stmt) break;
- CHECK_BB(emit_stmt(emit, stmt));
+ const Vector v = &emit->code->frame->defer;
+ for (m_uint i = vector_size(v) + 1; --i;) {
+ const Stmt s = (Stmt)vector_at(v, i - 1);
+ if (!s) break;
+ CHECK_BB(emit_stmt(emit, s));
}
return GW_OK;
}
(VMValue *)m_vector_addr(&emit->code->live_values, --frame->value_count);
vmval->end = emit_code_size(emit);
if (!tflag(l->type, tflag_struct)) return (m_int)l->offset;
- struct_pop(emit, l->type, l->offset);
+ emit_struct_release(emit, l->type, l->offset);
return _frame_pop(emit);
}
struct M_Vector_ vals = { .ptr = mv->ptr };
for(m_uint j = 0; j < m_vector_size(&vals); j++) {
const VMValue val = *(VMValue*)(vals.ptr + ARRAY_OFFSET + j * sizeof(VMValue));
- if(!tflag(val.t, tflag_struct)) {
- const Instr instr = emit_add_instr(emit, ObjectRelease);
- instr->m_val = val.offset;
- } else struct_pop(emit, val.t, val.offset);
+ emit_compound_release(emit, val.t, val.offset);
}
}
}
if(!vector_size(&v))
vector_release(&v);
else if(vector_size(&v) == 1) {
- Instr instr = emit_add_instr(emit, ObjectRelease);
- instr->m_val = vector_front(&v);
+ emit_object_release(emit, vector_front(&v));
vector_release(&v);
} else {
Instr instr = emit_add_instr(emit, ObjectRelease2);
if (isa(t, emit->gwion->type[et_compound]) > 0) {
l->is_compound = true;
VMValue vmval = {
- .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+ .t = t,
+ .offset = l->offset,
+ .start = emit_code_size(emit)
+ };
m_vector_add(&emit->code->live_values, &vmval);
++emit->code->frame->value_count;
}
Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t);
l->is_compound = true;
VMValue vmval = {
- .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+ .t = t,
+ .offset = l->offset,
+ .start = emit_code_size(emit)
+ };
m_vector_add(&emit->code->live_values, &vmval);
++emit->code->frame->value_count;
- l->instr = emit_add_instr(emit, Reg2Mem);
- l->instr->m_val = l->offset;
- l->instr->m_val2 = -SZ_INT;
+ l->instr = emit_regtomem(emit, l->offset, -SZ_INT);
return l;
}
ANN m_uint emit_local_exp(const Emitter emit, const Exp e) {
Local *const l = emit_localx(emit, e->type);
- if(e->ref)
- e->ref->data = l;
+ if(e->ref) e->ref->data = l;
return l->offset;
}
const Instr prelude = emit_add_instr(emit, SetCode);
prelude->m_val = -SZ_INT * 2;
prelude->udata.one = 2;
- emit_add_instr(emit, Reg2Mem);
+ (void)emit_regtomem(emit, 0, 0);
const Instr next = emit_add_instr(emit, Overflow);
next->m_val2 = offset;
}
instr->f = v->d.fnum;
else
instr->m_val = v->d.num;
- instr->m_val2 = size;
}
return GW_OK;
}
static void emit_exp_addref1(const Emitter emit, const Exp exp, m_int size) {
const Type t = exp->cast_to ?: exp->type;
if (isa(t, emit->gwion->type[et_compound]) > 0)
- // emit_object_addref(emit, size, exp_getvar(exp));
- // else if(tflag(t, tflag_struct))
emit_compound_addref(emit, exp->type, size, exp_getvar(exp));
}
ANN static m_bool emit_range(const Emitter emit, Range *range) {
if (range->start)
-// CHECK_BB(emit_exp_pop_next(emit, range->start));
CHECK_BB(emit_exp(emit, range->start));
- else
- emit_pushimm(emit, 0);
+ else emit_pushimm(emit, 0);
if (range->end)
CHECK_BB(emit_exp(emit, range->end));
- else
- emit_pushimm(emit, -1);
+ else emit_pushimm(emit, -1);
return GW_OK;
}
instr->m_val2 = -SZ_INT - val->size;
emit_regmove(emit, SZ_INT);
} else {
- const Instr instr = emit_add_instr(emit, Reg2RegOther2);
+ const Instr instr = emit_add_instr(emit, Reg2RegOther);
instr->m_val = -key->size;
instr->m_val2 = key->size;
emit_regmove(emit, key->size);
}
ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array *array) {
- const Exp e = exp_self(array);
+ const Exp e = exp_self(array);
exp_setvar(array->base, get_emit_var(emit, array->base->type, exp_getvar(e)));
CHECK_BB(emit_exp(emit, array->base));
struct ArrayAccessInfo info = {
ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) {
const Exp_Primary *prim = prim_self(data);
struct SpecialId_ *spid = specialid_get(emit->gwion, *data);
- if (spid)
+ if (unlikely(spid))
return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR;
if(vflag(prim->value, vflag_fglobal)) exp_self(prim)->acquire = 1;
return emit_symbol(emit, prim_self(data));
if (!(emit->env->func &&
emit->env->func->def->base->xid == insert_symbol("@gack")))
emit_add_instr(emit, GackEnd);
- else {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val = SZ_INT;
- instr->m_val2 = -SZ_INT;
- }
+ else emit_regtomem(emit, SZ_INT, -SZ_INT);
return GW_OK;
}
const Type t = decl->type;
const bool emit_addr = exp_getvar(exp_self(decl));
if (decl->args) {
-//exp_setvar(decl->args, emit_addr);
- const Instr instr = (Instr)vector_back(&emit->code->instr);
CHECK_BB(emit_exp(emit, decl->args));
if (emit_addr) {
emit_regmove(emit, -t->size);
-// emit_regmove(emit, SZ_INT -t->size);
-// const Instr instr = emit_add_instr(emit, Reg2RegAddr);
- const Instr instr = emit_add_instr(emit, RegPushMem4);
-// emit_add_instr(emit, EOC);
-// instr->m_val = -SZ_INT;
-// vector_add(&emit->code->instr, (m_uint)instr);
+ emit_regpushmem4(emit, 0, 0);
}
return GW_OK;
}
}
if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global))
emit_object_addref(emit, 0, emit_addr);
- } else if (tflag(v->type, tflag_struct)) {
-// if (!emit_var)
-// decl->vd.value->from->offset = decl_non_static_offset(emit, decl, type);
- CHECK_BB(struct_finish(emit, decl));
- }
+ } else if (tflag(v->type, tflag_struct))
+ CHECK_BB(struct_finish(emit, decl));
return GW_OK;
}
nspc_add_value(emit->env->curr, arg->var_decl.xid, value);
}
emit_regmove(emit, -f->code->stack_depth);
- const Instr cpy = emit_add_instr(emit, Reg2Mem4);
- cpy->m_val2 = f->code->stack_depth;
- cpy->m_val = start_offset;
+ emit_regtomem4(emit, f->code->stack_depth, start_offset);
}
ANN static inline void inline_args_end(const Func f, const Vector v) {
CHECK_BB(emit_func_args(emit, call));
if(back)
vector_add(&emit->code->instr, (m_uint)back);
- else if(tflag(t, tflag_ctor)) {
- const Instr instr = emit_add_instr(emit, RegPushMem4);
- instr->m_val = offset;
- }
+ else if(tflag(t, tflag_ctor))
+ emit_regpushmem4(emit, offset, 0);
if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
else if(!back) {
emit_regmove(emit, -SZ_INT + t->size);
- const Instr instr = emit_add_instr(emit, RegPushMem4);
- instr->m_val = offset;
+ emit_regpushmem4(emit, offset, 0);
}
emit_add_instr(emit, NoOp);
return GW_OK;
ANN static void emit_args(const Emitter emit, const Func f) {
const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
- if ((f->def->stack_depth - member) == SZ_INT) {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val = member;
- } else {
- const Instr instr = emit_add_instr(emit, Reg2Mem4);
- instr->m_val = member;
- instr->m_val2 = f->def->stack_depth - member;
- }
+ if ((f->def->stack_depth - member) == SZ_INT)
+ emit_regtomem(emit, member, 0);
+ else
+ emit_regtomem4(emit, member, f->def->stack_depth - member);
}
typedef struct {
prelude->m_val += -f->def->stack_depth - SZ_INT;
const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
if (member) {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val2 = f->def->stack_depth - SZ_INT;
+ emit_regtomem(emit, 0, f->def->stack_depth - SZ_INT);
++prelude->m_val2;
}
if (f->def->stack_depth - member) {
vector_add(&emit->code->stack_break, (vtype)NULL);
}
-ANN static void pop_vector(Vector v, const m_uint pc) {
- Instr instr;
- while ((instr = (Instr)vector_pop(v))) instr->m_val = pc;
+ANN static void set_pcs(const Vector v, const m_uint pc) {
+ m_uint i;
+ for(i = vector_size(v) + 1; --i;) {
+ Instr instr = (Instr)vector_at(v, i - 1);
+ if(!instr) break;
+ instr->m_val = pc;
+ }
+ VLEN(v) = i - 1;
+ vector_realloc(v);
}
ANN static void emit_pop_stack(const Emitter emit, const m_uint index) {
- pop_vector(&emit->code->stack_cont, index);
- pop_vector(&emit->code->stack_break, emit_code_size(emit));
+ set_pcs(&emit->code->stack_cont, index);
+ set_pcs(&emit->code->stack_break, emit_code_size(emit));
emit_pop_scope(emit);
}
? */emit_local(emit, emit->gwion->type[et_int])
/*: emit_local(emit, stmt->idx->v->type)*/;
const m_uint val_offset = emit_localn(emit, stmt->v->type); // localn ?
- const Instr tomem = emit_add_instr(emit, Reg2Mem);
- tomem->m_val = arr_offset;
+ emit_regtomem(emit, arr_offset, 0);
const Instr loop_idx = emit_add_instr(emit, MemSetImm);
loop_idx->m_val = key_offset;
loop_idx->m_val2 = -1;
}
CHECK_BB(emit_exp_pop_next(emit, stmt->cond));
emit_regmove(emit, -SZ_INT);
- const Instr tomem = emit_add_instr(emit, Reg2Mem);
- tomem->m_val = offset + (!stmt->idx ? 0 : SZ_INT);
+ emit_regtomem(emit, offset + !!stmt->idx * SZ_INT, 0);
*index = emit_code_size(emit);
struct Looper loop = {.exp = stmt->cond,
.stmt = stmt->body,
ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
const Value v = e->d.prim.value;
v->from->offset = emit_local(emit, base->type);
- emit_debug(emit, v);
- const Instr instr = emit_add_instr(emit, Reg2Mem4);
- instr->m_val = v->from->offset;
- instr->m_val2 = base->type->size;
+ emit_regtomem4(emit, v->from->offset, base->type->size);
return GW_OK;
}
}
ANN static void me_bottom(MemoizeEmitter *me, const m_uint pc) {
- const Instr idx = emit_add_instr(me->emit, RegPushMem4);
- idx->m_val = me->offset;
+ emit_regpushmem4(me->emit, me->offset, 0);
emit_add_instr(me->emit, int_pre_inc);
emit_regmove(me->emit, -SZ_INT);
const Instr loop = emit_add_instr(me->emit, Goto);
for(uint32_t i = 0; i < fdef->captures->len - 1; i++)
(void)get_capture(emit, fdef->captures, i);
const Capture *cap = get_capture(emit, fdef->captures, fdef->captures->len - 1);
- const Instr instr = emit_add_instr(emit, Reg2Mem4);
- instr->m_val = fdef->stack_depth;
- instr->m_val2 = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth;
+ const m_uint offset = cap->temp->from->offset + cap->temp->type->size - fdef->stack_depth;
+ emit_regtomem4(emit, fdef->stack_depth, offset);
}
ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) {
&®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr,
&®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr,
&®pushmemderef, &&pushnow, &&baseint, &&basefloat, &&baseother,
- &&baseaddr, &®toreg, &®toregother, &®toregother2, &®toregaddr, &®toregderef,
+ &&baseaddr, &®toreg, &®toregother2, &®toregaddr, &®toregderef,
&&structmember, &&structmemberfloat, &&structmemberother,
&&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat,
&®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint,
&®tomem, &®tomemother,
&&overflow,
&&funcusrend, &&funcusrend2, &&funcmemberend,
- &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkcode,
+ &&sporkini, &&forkini, &&sporkfunc, &&sporkexp, &&sporkcode,
&&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
&&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop,
&&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref,
regtoreg:
*(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2);
DISPATCH()
- regtoregother:
- memcpy(*(m_bit **)(reg - SZ_INT), reg + IVAL, VAL2);
- DISPATCH()
regtoregother2:
memcpy(reg - VAL2, reg + IVAL, VAL2);
DISPATCH()
*(m_float *)(reg - SZ_FLOAT) += vm->bbq->pos;
VM_OUT
break;
- recurs : {
+ recurs:
+ {
register const uint push = SVAL2;
mem += push;
*(frame_t *)(mem - sizeof(frame_t)) =
*(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2);
child->reg += VAL;
DISPATCH()
- sporkmemberfptr:
- 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) = *(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()
sporkexp:
// LOOP_OPTIM
for (m_uint i = 0; i < VAL; i += SZ_INT)
reg += SZ_INT;
DISPATCH()
dotmembermem:
- reg += SZ_INT;
- *(m_uint *)(reg - SZ_INT) =
+ *(m_uint *)reg =
*(m_uint *)((*(M_Object *)(mem + VAL2))->data + VAL);
+ reg += SZ_INT;
DISPATCH()
dotmembermem2:
- reg += SZ_INT - SZ_FLOAT;
- *(m_float *)(reg - SZ_FLOAT) =
+ *(m_float *)(reg + SZ_INT) =
*(m_float *)((*(M_Object *)(mem + VAL2))->data + VAL);
+ reg += SZ_INT - SZ_FLOAT;
DISPATCH()
// dotmembermem3:
dotmembermem4:
- reg += SZ_INT;
- *(m_bit **)(reg - SZ_INT) =
+ *(m_bit **)reg =
((*(M_Object *)(mem + VAL2))->data + VAL);
+ reg += SZ_INT;
DISPATCH()
dotmember:
*(m_uint *)(reg - SZ_INT) =
&&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr,
&&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr,
&&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother,
- &&_baseaddr, &&_regtoreg, &&_regtoregother, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef,
+ &&_baseaddr, &&_regtoreg, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef,
&&_structmember, &&_structmemberfloat, &&_structmemberother,
&&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat,
&&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint,
&&_regtomem, &&_regtomemother,
&&_overflow,
&&_funcusrend, &&_funcusrend2, &&_funcmemberend,
- &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp, &&_sporkcode, &&_forkend,
+ &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkexp, &&_sporkcode, &&_forkend,
&&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat,
&&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop,
&&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref,
PREPARE(baseother);
PREPARE(baseaddr);
PREPARE(regtoreg);
- PREPARE(regtoregother);
PREPARE(regtoregother2);
PREPARE(regtoregaddr);
PREPARE(regtoregderef);
PREPARE(sporkini);
PREPARE(forkini);
PREPARE(sporkfunc);
- PREPARE(sporkmemberfptr);
PREPARE(sporkexp);
PREPARE(sporkcode);
PREPARE(forkend);