From: fennecdjay Date: Tue, 27 Aug 2019 08:14:03 +0000 (+0200) Subject: :bug: Fix return stmt with multiple expressions X-Git-Tag: nightly~2259 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=116198c20d371500d91dae6e751f118d86238a18;p=gwion.git :bug: Fix return stmt with multiple expressions --- diff --git a/src/emit/emit.c b/src/emit/emit.c index 9c67e35a..8ef5187b 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1164,12 +1164,46 @@ ANN static m_bool optimize_taill_call(const Emitter emit, const Exp_Call* e) { return GW_OK; } +ANN static m_uint get_decl_size(Var_Decl_List a) { + m_uint size = 0; + do //if(GET_FLAG(a->self->value, used)) + size += a->self->value->type->size; + while((a = a->next)); + return size; +} + +ANN static m_uint pop_exp_size(const Emitter emit, Exp e) { + m_uint size = 0; + do { + if(e->exp_type == ae_exp_primary && + e->d.exp_primary.primary_type == ae_primary_hack) { + size += pop_exp_size(emit, e->d.exp_primary.d.exp); + continue; + } + size += (e->exp_type == ae_exp_decl ? + get_decl_size(e->d.exp_decl.list) : e->type->size); + } while((e = e->next)); + return size; +} + +ANN static inline void pop_exp(const Emitter emit, Exp e) { + const m_uint size = pop_exp_size(emit, e); + if(size) + regpop(emit, size); +} + +ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e) { + CHECK_BB(emit_exp(emit, e, 0)) + if(e->next) + pop_exp(emit, e->next); + return GW_OK; +} ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { if(stmt->val) { if(stmt->val->exp_type == ae_exp_call && emit->env->func == stmt->val->d.exp_call.m_func) return optimize_taill_call(emit, &stmt->val->d.exp_call); - CHECK_BB(emit_exp(emit, stmt->val, 0)) + CHECK_BB(emit_exp_pop_next(emit, stmt->val)) if(isa(stmt->val->type, t_object) > 0 && isa(stmt->val->type , t_shred) < 0) // beware shred emit_add_instr(emit, RegAddRef); } @@ -1205,41 +1239,6 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) { emit_pop_scope(emit); } -ANN static m_uint get_decl_size(Var_Decl_List a) { - m_uint size = 0; - do //if(GET_FLAG(a->self->value, used)) - size += a->self->value->type->size; - while((a = a->next)); - return size; -} - -ANN static m_uint pop_exp_size(const Emitter emit, Exp e) { - m_uint size = 0; - do { - if(e->exp_type == ae_exp_primary && - e->d.exp_primary.primary_type == ae_primary_hack) { - size += pop_exp_size(emit, e->d.exp_primary.d.exp); - continue; - } - size += (e->exp_type == ae_exp_decl ? - get_decl_size(e->d.exp_decl.list) : e->type->size); - } while((e = e->next)); - return size; -} - -ANN static inline void pop_exp(const Emitter emit, Exp e) { - const m_uint size = pop_exp_size(emit, e); - if(size) - regpop(emit, size); -} - -ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e) { - CHECK_BB(emit_exp(emit, e, 0)) - if(e->next) - pop_exp(emit, e->next); - return GW_OK; -} - ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) { CHECK_BO(emit_exp_pop_next(emit, e)) const f_instr instr_i = b ? BranchEqInt : BranchNeqInt;