]> Nishi Git Mirror - gwion.git/commitdiff
:art: update ast, track origin, fix foreach with Array[][]
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 22 Mar 2022 13:17:13 +0000 (14:17 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 22 Mar 2022 13:17:13 +0000 (14:17 +0100)
ast
include/instr.h
src/emit/emit.c
src/emit/emitter.c
src/lib/array.c
src/lib/instr.c
src/lib/object_op.c

diff --git a/ast b/ast
index 971a79a2f613db01129d7e52b4f738640bee00a9..bf27a9f9f37420e80cfeca031f465a338ebbe63b 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 971a79a2f613db01129d7e52b4f738640bee00a9
+Subproject commit bf27a9f9f37420e80cfeca031f465a338ebbe63b
index 03a10109a9a1b53e43a5ba71ebabd6f6bb9d5a85..9e0ce934dc2dd999d0a9f27c47f9392303c2c60a 100644 (file)
@@ -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 */
index abafa0d92d5530f84eb1d50ca5a08d3e22df0878..96b323152878464d11435f1ea2cd71774afc5ec3 100644 (file)
@@ -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;
 }
index 82026861e6981e234c42fc60b7be5704726937e0..43faa8133725d31249c9aa40abd14d0f5b7fec49 100644 (file)
@@ -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;
+  }
+}
index edbbdcc019145d5a4bb44fe957cbe046e9765f1c..d0a4552f76ef99fbb97820f8e85d605769f316b9 100644 (file)
@@ -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;
index 0a138a0677850e3e1b5ee4deb4233118efde8021..1e3843ec00af9d5854e69b6ed16eb7b3f5adb318 100644 (file)
@@ -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");
 }
index b704b764477454a29b2f9dc87b04337197711b73..3d3e6f20e69226295f9f2ef1612bdfc51c9ffb35 100644 (file)
@@ -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;
 }