From 1546126355b0f76f40c93c78d2e34da8c2067445 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Tue, 22 Mar 2022 14:17:13 +0100 Subject: [PATCH] :art: update ast, track origin, fix foreach with Array[][] --- ast | 2 +- include/instr.h | 6 ++++++ src/emit/emit.c | 31 ++++++++----------------------- src/emit/emitter.c | 12 ++++++++++++ src/lib/array.c | 28 +++++++++++++++++++++------- src/lib/instr.c | 23 ++++++++++++++++------- src/lib/object_op.c | 7 ++----- 7 files changed, 66 insertions(+), 43 deletions(-) diff --git a/ast b/ast index 971a79a2..bf27a9f9 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 971a79a2f613db01129d7e52b4f738640bee00a9 +Subproject commit bf27a9f9f37420e80cfeca031f465a338ebbe63b diff --git a/include/instr.h b/include/instr.h index 03a10109..9e0ce934 100644 --- a/include/instr.h +++ b/include/instr.h @@ -43,6 +43,12 @@ INSTR(DtorReturn); INSTR(ComplexReal); INSTR(ComplexImag); +struct FastExceptInfo { + m_str file; + loc_t loc; + m_str file2; + loc_t loc2; +}; INSTR(fast_except); /* function */ diff --git a/src/emit/emit.c b/src/emit/emit.c index abafa0d9..96b32315 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -518,12 +518,8 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) { instr->m_val = (m_uint)&v->d.ptr; // prevent invalid access to global variables if(!exp_getvar(exp_self(prim_self(data))) && - isa(v->type, emit->gwion->type[et_object]) > 0) { -// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - const Instr instr = emit_add_instr(emit, fast_except); - instr->m_val = -SZ_INT; - // use m_val2 to set some info? - } + isa(v->type, emit->gwion->type[et_object]) > 0) + emit_fast_except(emit, v->from, prim_pos(data)); } else { const m_uint size = v->type->size; const Instr instr = emit_regpushimm(emit, size, exp_getvar(prim_exp(data))); @@ -575,11 +571,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) { instr->m_val = v->from->offset; if (GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) && (isa(v->type, emit->gwion->type[et_object]) > 0 || - is_fptr(emit->gwion, v->type))) { -// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - const Instr instr = emit_add_instr(emit, fast_except); - instr->m_val = -SZ_INT; - } + is_fptr(emit->gwion, v->type))) + emit_fast_except(emit, v->from, prim_pos(data)); return GW_OK; } @@ -755,11 +748,8 @@ ANN m_bool emit_array_access(const Emitter emit, .rhs = info->array.type, .data = (uintptr_t)info}; if (!info->is_var && - (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type))) { -// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - const Instr instr = emit_add_instr(emit, fast_except); - instr->m_val = -SZ_INT; - } + (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type))) + emit_fast_except(emit, NULL, info->array.exp->pos); return op_emit(emit, &opi); } @@ -2139,13 +2129,8 @@ ANN2(1) /*static */ m_bool emit_exp(const Emitter emit, /* const */ Exp e) { (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) && e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && exp_getuse(e) && !exp_getvar(e) && - GET_FLAG(mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value, late)) { -// GET_FLAG(e->d.exp_decl.list->self->value, late)) { - // e->exp_type == ae_exp_decl && !exp_getvar(e)) { -// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - const Instr instr = emit_add_instr(emit, fast_except); - instr->m_val = -SZ_INT; - } + GET_FLAG(mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value, late)) + emit_fast_except(emit, mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value->from, e->pos); } while ((exp = exp->next)); return GW_OK; } diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 82026861..43faa813 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -47,3 +47,15 @@ __attribute__((returns_nonnull)) ANN2(1) Instr vector_add(&emit->code->instr, (vtype)instr); return instr; } + +ANN2(1) void emit_fast_except(const Emitter emit, const struct ValueFrom_ *vf, const loc_t loc) { + const Instr instr = emit_add_instr(emit, fast_except); + if(vf) { + struct FastExceptInfo *info = mp_malloc2(emit->gwion->mp, sizeof(struct FastExceptInfo)); + info->file = emit->env->name; + info->loc = loc; + info->file2 = vf->filename; + info->loc2 = vf->loc; + instr->m_val2 = (m_uint)info; + } +} diff --git a/src/lib/array.c b/src/lib/array.c index edbbdcc0..d0a4552f 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -289,14 +289,18 @@ static FREEARG(freearg_array) { ANN Type check_array_access(const Env env, const Array_Sub array); +ANN static inline Type get_array_type(const Type type) { + const Type t = !tflag(type, tflag_ref) ? type : (Type)vector_front(&type->info->tuple->contains); + return t->array_depth ? t : typedef_base(t); +} + static OP_CHECK(opck_array) { const Array_Sub array = (Array_Sub)data; const Type t_int = env->gwion->type[et_int]; Exp e = array->exp; do CHECK_BN(check_implicit(env, e, t_int)); while ((e = e->next)); - const Type t = - array->type->array_depth ? array->type : typedef_base(array->type); + const Type t = get_array_type(array->type); if (t->array_depth >= array->depth) return array_type(env, array_base(t), t->array_depth - array->depth); const Exp curr = take_exp(array->exp, t->array_depth); @@ -356,17 +360,27 @@ ANN static inline Exp emit_n_exp(const Emitter emit, return ret > 0 ? next : NULL; } +ANN static Type emit_get_array_type(const Emitter emit, const Type t) { + if(!tflag(t, tflag_ref)) return t; + const Instr instr = emit_add_instr(emit, Reg2RegDeref); + instr->m_val = -SZ_INT; + instr->m_val2 = -SZ_INT; + return (Type)vector_front(&t->info->tuple->contains); + +} + static OP_EMIT(opem_array_access) { struct ArrayAccessInfo *const info = (struct ArrayAccessInfo *)data; - if (info->array.type->array_depth >= info->array.depth) { + const Type t = emit_get_array_type(emit, info->array.type); + if (t->array_depth >= info->array.depth) { struct Array_Sub_ next = { .exp = info->array.exp, .type = info->type, .depth = info->array.depth}; return array_do(emit, &next, info->is_var); } - struct Array_Sub_ partial = {info->array.exp, info->array.type, - info->array.type->array_depth}; - struct Array_Sub_ next = {info->array.exp, array_base(info->array.type), - info->array.depth - info->array.type->array_depth}; + struct Array_Sub_ partial = {info->array.exp, t, + t->array_depth}; + struct Array_Sub_ next = {info->array.exp, array_base(t), + info->array.depth - t->array_depth}; info->array = partial; const Exp exp = emit_n_exp(emit, info); next.exp = exp; diff --git a/src/lib/instr.c b/src/lib/instr.c index 0a138a06..1e3843ec 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -150,11 +150,20 @@ INSTR(SetCtor) { } INSTR(fast_except) { - if(*(m_uint*)REG((m_int)instr->m_val)) { -// BYTE(eNoOp) - m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \ - *(m_uint *)byte = instr->opcode; - instr->opcode = eNoOp; - } else - handle(shred, "NullPtrException"); + struct FastExceptInfo *info = (struct FastExceptInfo *)instr->m_val2; + if(*(m_uint*)REG(-SZ_INT)) { + m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \ + *(m_uint *)byte = instr->opcode; + VAL = -SZ_INT; + instr->opcode = eNoOp; + if(info) mp_free2(shred->info->mp, sizeof(struct FastExceptInfo), info); + return; + } else if(info) { + if(info->file) + gwerr_basic("Object not instantiated", NULL, NULL, info->file, info->loc, 0); + if(info->file2) + gwerr_warn("declared here", NULL, NULL, info->file2, info->loc2); + mp_free2(shred->info->mp, sizeof(struct FastExceptInfo), info); + } + handle(shred, "NullPtrException"); } diff --git a/src/lib/object_op.c b/src/lib/object_op.c index b704b764..3d3e6f20 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -275,11 +275,8 @@ OP_EMIT(opem_object_dot) { } if((isa(value->type, emit->gwion->type[et_object]) > 0 || is_fptr(emit->gwion, value->type)) && !exp_getvar(exp_self(member)) && - (GET_FLAG(value, static) || GET_FLAG(value, late))) { -// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); - const Instr instr = emit_add_instr(emit, fast_except); - instr->m_val = -SZ_INT; - } + (GET_FLAG(value, static) || GET_FLAG(value, late))) + emit_fast_except(emit, value->from, exp_self(member)->pos); return GW_OK; } -- 2.43.0