Frame* frame = mp_calloc(p, Frame);
vector_init(&frame->stack);
vector_add(&frame->stack, (vtype)NULL);
+ vector_init(&frame->defer);
+ vector_add(&frame->defer, (vtype)NULL);
return frame;
}
ANN static inline void frame_push(Frame* frame) {
vector_add(&frame->stack, (vtype)NULL);
+ vector_add(&frame->defer, (vtype)NULL);
}
static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
}
}
-ANN static m_int frame_pop(const Emitter emit) {
+ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop);
+
+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, 1))
+ 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, 1))
+ }
+ return GW_OK;
+}
+
+ANN static m_int _frame_pop(const Emitter emit) {
Frame *frame = emit->code->frame;
DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
frame->curr_offset -= l->type->size;
if(l->skip)
- return frame_pop(emit);
+ return _frame_pop(emit);
if(tflag(l->type, tflag_struct)) {
struct_pop(emit, l->type, l->offset);
- return frame_pop(emit);
+ return _frame_pop(emit);
}
- return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset : frame_pop(emit);
+ return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset : _frame_pop(emit);
+}
+
+ANN static m_int frame_pop(const Emitter emit) {
+ emit_defers(emit);
+ return _frame_pop(emit);
}
ANN /*static */m_bool emit_exp(const Emitter emit, Exp exp);
}
ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) {
+ CHECK_BB(emit_defers2(emit))
if(stmt->val) {
if(stmt->val->exp_type == ae_exp_call) {
const Func f = stmt->val->d.exp_call.func->type->info->func;
}
ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt_Index stmt) {
+ CHECK_BB(emit_defers2(emit))
if(stmt->idx == -1 || stmt->idx == 1)
vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto));
else if(stmt->idx) {
}
ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt_Index stmt NUSED) {
+ CHECK_BB(emit_defers2(emit))
if(stmt->idx == -1 || stmt->idx == 1)
vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto));
else if(stmt->idx) {
*index = emit_code_size(emit);
struct Looper loop = { .stmt=stmt->body, .offset=offset, .n=n,
.roll=stmt_loop_roll };
-//roll(emit, &loop);
CHECK_BB(looper_run(emit, &loop))
const Instr _goto = emit_add_instr(emit, Goto);
_goto->m_val = *index;
return GW_OK;
}
+ANN static m_bool emit_stmt_defer(const Emitter emit, const struct Stmt_Defer_* stmt) {
+ vector_add(&emit->code->frame->defer, (m_uint)stmt->stmt);
+ return GW_OK;
+}
+
#define emit_stmt_while emit_stmt_flow
#define emit_stmt_until emit_stmt_flow
DECL_STMT_FUNC(emit, m_bool , Emitter)
vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
}
-ANN static void emit_func_def_return(const Emitter emit) {
+ANN static m_bool emit_func_def_return(const Emitter emit) {
const m_uint val = emit_code_size(emit);
+ CHECK_BB(emit_defers(emit))
LOOP_OPTIM
for(m_uint i = vector_size(&emit->code->stack_return) + 1; --i; ) {
const Instr instr = (Instr)vector_at(&emit->code->stack_return, i-1);
const Instr instr = emit_add_instr(emit, MemoizeStore);
instr->m_val = emit->env->func->def->stack_depth;
}
+ return GW_OK;
}
ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) {
do CHECK_BB(emit_section(emit, ast->section))
while((ast = ast->next));
- return GW_OK;
+ return emit_defers(emit);
}
ANN m_bool emit_ast(const Env env, Ast ast) {