From 5c2f2f1e71c9406e58df40ddbc7d0018ca408d1d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Fri, 18 Dec 2020 02:26:11 +0100 Subject: [PATCH] :art: Indexed jumps (add files) --- src/emit/emit.c | 54 +++++++++++++++++++++++++-------------------- src/env/context.c | 6 ----- src/env/env_utils.c | 4 ---- src/lib/union.c | 1 - src/parse/check.c | 16 -------------- src/parse/scan1.c | 1 - src/parse/scan2.c | 25 --------------------- 7 files changed, 30 insertions(+), 77 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index b2246733..42231c90 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1511,13 +1511,39 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { return GW_OK; } -ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt stmt NUSED) { - vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto)); +ANN static inline m_bool emit_jump_index(const Emitter emit, const Vector v, const m_int n) { + vector_add(v, 0); // make room + const m_uint sz = vector_size(v); + m_int idx = 1; + for(m_uint i = sz; --i > 1;) { + if(!vector_at(v, i) && ++idx == n) { + m_uint *data = v->ptr + OFFSET + i*SZ_INT; + memcpy(data + SZ_INT, data, (sz-i) * SZ_INT); + const Instr instr = emit_add_instr(emit, Goto); + VPTR(v, i-1) = (m_uint)instr; + return GW_OK; + } + } + return GW_ERROR; +} + +ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt_Index stmt) { + if(stmt->idx == -1 || stmt->idx == 1) + vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto)); + else if(stmt->idx) { + if(emit_jump_index(emit, &emit->code->stack_cont, stmt->idx) < 0) + ERR_B(stmt_self(stmt)->pos, _("to many jumps required.")) + } return GW_OK; } -ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt stmt NUSED) { - vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto)); +ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt_Index stmt NUSED) { + if(stmt->idx == -1 || stmt->idx == 1) + vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto)); + else if(stmt->idx) { + if(emit_jump_index(emit, &emit->code->stack_break, stmt->idx) < 0) + ERR_B(stmt_self(stmt)->pos, _("to many jumps required.")) + } return GW_OK; } @@ -1671,26 +1697,6 @@ ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) { return ret; } -ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) { - if(!stmt->is_label) - stmt->data.instr = emit_add_instr(emit, Goto); - else { - assert(stmt->data.v.ptr); - const m_uint size = vector_size(&stmt->data.v); - if(!size) -//return GW_OK; - ERR_B(stmt_self(stmt)->pos, _("label '%s' defined but not used."), s_name(stmt->name)) - LOOP_OPTIM - for(m_uint i = size + 1; --i;) { - const Stmt_Jump label = (Stmt_Jump)vector_at(&stmt->data.v, i - 1); - if(!label->data.instr) - ERR_B(stmt_self(label)->pos, _("you are trying to use a upper label.")) - label->data.instr->m_val = emit_code_size(emit); - } - } - return GW_OK; -} - ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) { return (!is_fptr(emit->gwion, tdef->type) && tdef->type->info->cdef) ? emit_class_def(emit, tdef->type->info->cdef) : GW_OK; diff --git a/src/env/context.c b/src/env/context.c index c78d522e..a3b1dbe7 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -27,12 +27,6 @@ ANN void load_context(const Context context, const Env env) { } ANN void unload_context(const Context context, const Env env) { - if(context->lbls.ptr) { - LOOP_OPTIM - for(m_uint i = 0; i < map_size(&context->lbls); i++) - free_map(env->gwion->mp, (Map)map_at(&context->lbls, i)); - map_release(&context->lbls); - } context_remref(context, env->gwion); env->curr = (Nspc)vector_pop(&env->scope->nspc_stack); } diff --git a/src/env/env_utils.c b/src/env/env_utils.c index 58e556da..3fbb8026 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -5,10 +5,6 @@ #include "vm.h" #include "parse.h" -ANN Map env_label(const Env env) { - return &env->context->lbls; -} - #define GET(a,b) ((a) & (b)) == (b) ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos) { if(env->scope->depth) { diff --git a/src/lib/union.c b/src/lib/union.c index d9b770a7..3c94146a 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -86,7 +86,6 @@ static OP_CHECK(opck_union_is) { if(!strcmp(s_name(exp->d.prim.d.var), v->name)) { *mut = 1; const Exp exp_func = call->func; - const Exp exp_base = call->func->d.exp_dot.base; const Exp exp_args = call->args; e->exp_type = ae_exp_binary; e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func); diff --git a/src/parse/check.c b/src/parse/check.c index bf90bd57..1d0b3d80 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1021,22 +1021,6 @@ ANN static m_bool check_stmt_##name(const Env env, const Stmt stmt) {\ describe_check_stmt_stack(conts, continue) describe_check_stmt_stack(breaks, break) -ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) { - if(stmt->is_label) - return GW_OK; - const Map label = env_label(env); - const m_uint* key = env->class_def && !env->func ? - (m_uint*)env->class_def : (m_uint*)env->func; - const Map m = label->ptr ? (Map)map_get(label, (vtype)key) : NULL; - if(!m) - ERR_B(stmt_self(stmt)->pos, _("label '%s' used but not defined"), s_name(stmt->name)) - const Stmt_Jump ref = (Stmt_Jump)map_get(m, (vtype)stmt->name); - if(!ref) - ERR_B(stmt_self(stmt)->pos, _("label '%s' used but not defined"), s_name(stmt->name)) - vector_add(&ref->data.v, (vtype)stmt); - return GW_OK; -} - ANN m_bool check_union_def(const Env env NUSED, const Union_Def udef) { if(tmpl_base(udef->tmpl)) // there's a func for this return GW_OK; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 8377b33c..d9c6e5fe 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -440,7 +440,6 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) { #define scan1_stmt_until scan1_stmt_flow #define scan1_stmt_continue (void*)dummy_func #define scan1_stmt_break (void*)dummy_func -#define scan1_stmt_jump (void*)dummy_func #define scan1_stmt_return scan1_stmt_exp ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) { diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 9af08dbf..e36fec94 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -234,31 +234,6 @@ ANN static inline m_bool scan2_stmt_exp(const Env env, const Stmt_Exp stmt) { return stmt->val ? scan2_exp(env, stmt->val) : 1; } -__attribute__((returns_nonnull)) -ANN static Map scan2_label_map(const Env env) { - Map m, label = env_label(env); - const m_uint* key = env->class_def && !env->func ? - (m_uint*)env->class_def : (m_uint*)env->func; - if(!label->ptr) - map_init(label); - if(!(m = (Map)map_get(label, (vtype)key))) { - m = new_map(env->gwion->mp); - map_set(label, (vtype)key, (vtype)m); - } - return m; -} - -ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { - if(stmt->is_label) { - const Map m = scan2_label_map(env); - if(map_get(m, (vtype)stmt->name)) - ERR_B(stmt_self(stmt)->pos, _("label '%s' already defined"), s_name(stmt->name)) - map_set(m, (vtype)stmt->name, (vtype)stmt); - vector_init(&stmt->data.v); - } - return GW_OK; -} - ANN m_bool scan2_union_def(const Env env NUSED, const Union_Def udef) { if(tmpl_base(udef->tmpl)) return GW_OK; -- 2.43.0