]> Nishi Git Mirror - gwion.git/commitdiff
:art: Ptr as a struct
authorJérémie Astor <fennecdjay@gmail.com>
Sat, 21 Nov 2020 18:40:31 +0000 (19:40 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Sat, 21 Nov 2020 18:40:31 +0000 (19:40 +0100)
include/env/type.h
src/emit/emit.c
src/import/import_cdef.c
src/lib/object_op.c
src/lib/ptr.c
src/vm/vm.c

index 87c481e3a85207a813e03638e3177d15d85b8247..b6400d90490a5f25b90a01a54fcce99bbe1428e8 100644 (file)
@@ -64,11 +64,20 @@ static inline int safe_tflag(const Type t, const enum tflag flag) {
 ANN static inline void set_tflag(const Type t, const enum tflag flag) {
   t->tflag |= flag;
 }
+
+static inline void unset_tflag(const Type t, const enum tflag flag) {
+  t->tflag &= ~flag;
+}
 #else
 ANN static inline void set_tflag(const Type t, const enum tflag flag) {
   auto ff = t->tflag | flag;
   t->tflag = static_cast<enum tflag>(ff);
 }
+
+static inline void unset_tflag(const Type t, const enum tflag flag) {
+  const auto ff = t->tflag & ~flag;
+  t->tflag = static_cast<enum fflag>(tt);
+}
 #endif
 ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
 ANEW ANN Type type_copy(MemPool, const Type type);
index db61a193ce7d2fc0719d104953d3ccbb254d3be9..84925707d4438c7170e609dd278a7a6f057f75a0 100644 (file)
@@ -76,9 +76,68 @@ ANN static inline void frame_push(Frame* frame) {
   vector_add(&frame->stack, (vtype)NULL);
 }
 
+static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
+static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
+static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
+static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
+static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
+static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
+static const f_instr structmember[]  = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
+
+#define regxxx(name, instr) \
+ANN static inline Instr reg##name(const Emitter emit, const m_uint sz) { \
+  const Instr instr = emit_add_instr(emit, Reg##instr); \
+  instr->m_val = sz; \
+  return instr; \
+}
+regxxx(pop, Pop)
+regxxx(push, Push)
+regxxx(pushi, PushImm)
+regxxx(seti, SetImm)
+
+static inline enum Kind kindof(const m_uint size, const uint emit_var) {
+  if(emit_var)
+    return KIND_ADDR;
+  return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
+}
+
+ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
+  const enum Kind kind = kindof(size, addr);
+  const Instr instr = emit_add_instr(emit, func[kind]);
+  instr->m_val2 = size;
+  return instr;
+}
+
+ANN static void emit_struct_ctor(const Emitter emit, const Type type, const m_uint offset) {
+  emit->code->frame->curr_offset += SZ_INT;
+  const Instr instr = emit_add_instr(emit, RegPushMem4);
+  instr->m_val = offset;
+  const Instr tomem = emit_add_instr(emit, Reg2Mem);
+  tomem->m_val = emit->code->frame->curr_offset;
+  tomem->m_val2 = -SZ_INT;
+  regpushi(emit, (m_uint)type);
+  const Instr tomem2 = emit_add_instr(emit, Reg2Mem);
+  tomem2->m_val = emit->code->frame->curr_offset + SZ_INT;
+  tomem2->m_val2 = -SZ_INT;
+  const Instr set_code = regseti(emit, (m_uint)type->nspc->dtor);
+  set_code->m_val2 = SZ_INT;
+  const m_uint code_offset = emit_code_offset(emit);
+  const Instr regset = regseti(emit, code_offset);
+  regset->m_val2 = SZ_INT *2;
+  regpush(emit, SZ_INT *2);
+  const Instr prelude = emit_add_instr(emit, SetCode);
+  prelude->m_val2 = 2;
+  prelude->m_val = SZ_INT*3;
+  const Instr next = emit_add_instr(emit, Overflow);
+  next->m_val2 = code_offset;
+  emit->code->frame->curr_offset -= SZ_INT;
+}
+
 ANN static void struct_pop(const Emitter emit, const Type type, const m_uint offset) {
   if(!type->info->tuple)
     return;
+  if(type->nspc->dtor)
+    emit_struct_ctor(emit, type, offset);
   for(m_uint i = 0; i < vector_size(&type->info->tuple->types); ++i) {
     const Type t = (Type)vector_at(&type->info->tuple->types, i);
     if(isa(t, emit->gwion->type[et_object]) > 0) {
@@ -177,17 +236,6 @@ ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
     emit_array_extend(emit, type->info->parent, type->info->cdef->base.ext->array->exp);
 }
 
-#define regxxx(name, instr) \
-ANN static inline Instr reg##name(const Emitter emit, const m_uint sz) { \
-  const Instr instr = emit_add_instr(emit, Reg##instr); \
-  instr->m_val = sz; \
-  return instr; \
-}
-regxxx(pop, Pop)
-regxxx(push, Push)
-regxxx(pushi, PushImm)
-regxxx(seti, SetImm)
-
 ANN static void struct_expand(const Emitter emit, const Type t) {
   const Instr instr = emit_add_instr(emit, Reg2RegDeref);
   instr->m_val = -SZ_INT;
@@ -275,8 +323,7 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) {
   const m_uint offset = emit_code_offset(emit);
   const Instr regset = regseti(emit, offset);
   regset->m_val2 = SZ_INT *2;
-  const Instr push = emit_add_instr(emit, RegPush);
-  push->m_val = SZ_INT *2;
+  regpush(emit, SZ_INT*2);
   const Instr prelude = emit_add_instr(emit, SetCode);
   prelude->m_val2 = 2;
   prelude->m_val = SZ_INT;
@@ -310,27 +357,6 @@ ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
   return GW_OK;
 }
 
-static inline enum Kind kindof(const m_uint size, const uint emit_var) {
-  if(emit_var)
-    return KIND_ADDR;
-  return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
-}
-
-ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
-  const enum Kind kind = kindof(size, addr);
-  const Instr instr = emit_add_instr(emit, func[kind]);
-  instr->m_val2 = size;
-  return instr;
-}
-
-static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
-static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
-static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
-static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
-static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
-static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
-static const f_instr structmember[]  = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
-
 ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
   const Exp dot = symbol_owned_exp(emit->gwion, data);
@@ -1572,20 +1598,12 @@ ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) {
   return ret;
 }
 
-ANN static Instr emit_stmt_eachptr_init(const Emitter emit, const Type type) {
-  const Instr new_obj = emit_add_instr(emit, ObjectInstantiate);
-  new_obj->m_val2 = (m_uint)type;
-  (void)emit_addref(emit, 0);
-  regpop(emit, SZ_INT);
-  return emit_add_instr(emit, Reg2Mem);
-}
-
 ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_uint *end_pc) {
   const Instr s1 = emit_add_instr(emit, MemSetImm);
-  Instr cpy = stmt->is_ptr ? emit_stmt_eachptr_init(emit, stmt->v->type) : NULL;
+  Instr cpy = stmt->is_ptr ? emit_add_instr(emit, MemSetImm) : NULL;
   emit_local(emit, emit->gwion->type[et_int]);
   const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
-  emit_local(emit, emit->gwion->type[et_int]);
+  emit_local(emit, emit->gwion->type[et_ptr]);//et_int
   stmt->v->from->offset = offset + SZ_INT;
   const m_uint ini_pc  = emit_code_size(emit);
   emit_except(emit, stmt->exp->info->type);
index 9c6dbcaad21f8a01bf1db28a2b74fa16e6196507..27a95019e4789a25b7c233433d3dcec1e9d3c787 100644 (file)
@@ -102,11 +102,21 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
 }
 
 ANN Type gwi_struct_ini(const Gwi gwi, const m_str name) {
-  CHECK_OO(gwi_str2sym(gwi, name))
-  const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
-  t->info->tuple = new_tupleform(gwi->gwion->mp, NULL);
-  gwi_type_flag(t);
+  struct ImportCK ck = { .name=name };
+  CHECK_BO(check_typename_def(gwi, &ck))
+  const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), gwi->gwion->type[et_compound]);
   set_tflag(t, tflag_struct);
+  if(!ck.tmpl)
+    gwi_type_flag(t);
+  else {
+    t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, NULL, NULL, loc(gwi));
+    t->info->cdef->base.type = t;
+    t->info->cdef->base.tmpl = new_tmpl_base(gwi->gwion->mp, ck.tmpl);
+    t->info->tuple = new_tupleform(gwi->gwion->mp, NULL);
+    t->info->parent = NULL;
+    t->info->cdef->cflag |= cflag_struct;
+    set_tflag(t, tflag_tmpl);
+  }
   return type_finish(gwi, t);
 }
 
index 4b7f7111fd936a754d83972f9e7f6aeb8abf1ab7..795166b7bf5ae5c942d3a2ad4ea20b9d031c06de 100644 (file)
@@ -262,7 +262,6 @@ OP_EMIT(opem_object_dot) {
 }
 
 struct tmpl_info {
-//  const  Class_Def cdef;
   Symbol           name;
   ID_List          list;
   Type_List        call;
@@ -344,6 +343,7 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
       c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
     loc_cpy(env->gwion->mp, c->pos));
+  cdef->cflag = c->cflag;
   cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
   const m_bool ret = scan0_class_def(env, cdef);
   if((info->ret = cdef->base.type)) {
index c4e72def2813a50212a382146d0bdbb107db3332..bc8a94e6a714303897242aa518d6cb738571936d 100644 (file)
@@ -26,6 +26,7 @@ static OP_CHECK(opck_ptr_assign) {
   CHECK_BO(ptr_access(env, bin->lhs))
   CHECK_BO(ptr_access(env, bin->rhs))
   exp_setvar(bin->lhs, 1);
+  exp_setvar(bin->rhs, 1);
   Type t = bin->lhs->info->type;
   do {
 //    t = unflag_type(t);
@@ -41,10 +42,27 @@ static OP_CHECK(opck_ptr_assign) {
 }
 
 static INSTR(instr_ptr_assign) {
-  POP_REG(shred, SZ_INT)
-  const M_Object o = *(M_Object*)REG(0);
-  *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT);
-  _release(o, shred);
+  m_bit **o = *(m_bit***)REG(0);
+  *o = *(m_bit**)REG(-SZ_INT);
+}
+
+static INSTR(instr_ptr_assign_obj) {
+  m_bit **o = *(m_bit***)REG(0);
+  release(*(M_Object*)o, shred);
+  *o = *(m_bit**)REG(-SZ_INT);
+}
+
+static OP_EMIT(opem_ptr_assign) {
+  const Instr pop = emit_add_instr(emit, RegPop);
+  pop->m_val = SZ_INT;
+  const Exp_Binary* bin = (Exp_Binary*)data;
+  if(isa(bin->lhs->info->type, emit->gwion->type[et_object]) > 0) {
+    const Instr instr = emit_add_instr(emit, RegAddRefAddr);
+    instr->m_val = -SZ_INT;
+    emit_add_instr(emit, instr_ptr_assign_obj);
+  } else
+    emit_add_instr(emit, instr_ptr_assign);
+  return pop;
 }
 
 static OP_CHECK(opck_ptr_deref) {
@@ -86,21 +104,20 @@ static OP_CHECK(opck_ptr_implicit) {
 }
 
 static INSTR(instr_ptr_deref) {
-  const M_Object o = *(M_Object*)REG(-SZ_INT);
-  if(!*(m_bit**)o->data)
+  const m_bit *o = *(m_bit**)REG(-SZ_INT);
+  if(!o)
     Except(shred, _("EmptyPointerException"));
   if(instr->m_val2)
-    memcpy(REG(-SZ_INT), o->data, SZ_INT);
+    memcpy(REG(-SZ_INT), &o, SZ_INT);
   else {
     shred->reg -= SZ_INT - instr->m_val;
-    memcpy(REG(-instr->m_val), *(m_bit**)o->data, instr->m_val);
+    memcpy(REG(-instr->m_val), o, instr->m_val);
   }
 }
 
 static INSTR(Cast2Ptr) {
-  const M_Object o = new_object(shred->info->mp, shred, (Type)instr->m_val);
-  *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT);
-  *(M_Object*)REG(-SZ_INT) = o;
+  m_bit *o = *(m_bit**)REG(-SZ_INT);
+  *(m_bit**)REG(-SZ_INT) = o;
 }
 
 static OP_EMIT(opem_ptr_cast) {
@@ -128,23 +145,24 @@ static OP_EMIT(opem_ptr_deref) {
 ANN Type scan_class(const Env env, const Type t, const Type_Decl* td);
 
 static DTOR(ptr_object_dtor) {
-  release(*(M_Object*)o->data, shred);
+  release(**(M_Object**)o, shred);
 }
 
 static DTOR(ptr_struct_dtor) {
-  const Type t = (Type)vector_front(&o->type_ref->info->tuple->types);
-  struct_release(shred, t, *(m_bit**)o->data);
+  const Type base = *(Type*)(shred->mem + SZ_INT);
+  const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->owner_class, base->info->owner);
+  const Type t = known_type(shred->info->vm->gwion->env, base->info->cdef->base.tmpl->call->td);
+  env_pop(shred->info->vm->gwion->env, scope);
+  struct_release(shred, t, *(m_bit**)o);
 }
 
 static OP_CHECK(opck_ptr_scan) {
   struct TemplateScan *ts = (struct TemplateScan*)data;
   DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
-set_tflag(t, tflag_tmpl);
-//if(!tflag(t, tflag_scan1))exit(3);
   const Type base = known_type(env, t->info->cdef->base.tmpl->call->td);
-  if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
+  if(isa(base, env->gwion->type[et_compound]) > 0) {
     t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
-    if(!tflag(t, tflag_struct))
+    if(!tflag(base, tflag_struct))
       t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
     else
       t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
@@ -154,23 +172,19 @@ set_tflag(t, tflag_tmpl);
 }
 
 GWION_IMPORT(ptr) {
-  const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
-  GWI_BB(gwi_class_end(gwi))
-  set_tflag(_t_ptr, tflag_ntmpl);
-//  set_tflag(_t_ptr, tflag_tmpl);
-  GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
-  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
-  const Type t_ptr = gwi_class_ini(gwi, "Ptr:[A]", "@Ptr");
+  const Type t_ptr = gwi_struct_ini(gwi, "Ptr:[A]");
   gwi->gwion->type[et_ptr] = t_ptr;
   GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
   GWI_BB(gwi_item_end(gwi, 0, NULL))
   GWI_BB(gwi_class_end(gwi))
   set_tflag(t_ptr, tflag_ntmpl);
-//  set_tflag(t_ptr, tflag_tmpl);
+  GWI_BB(gwi_oper_ini(gwi, "Ptr", NULL, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
+  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
-  GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
+  GWI_BB(gwi_oper_emi(gwi, opem_ptr_assign))
+  GWI_BB(gwi_oper_end(gwi, ":=>", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_implicit))
   GWI_BB(gwi_oper_emi(gwi, opem_ptr_implicit))
   GWI_BB(gwi_oper_end(gwi, "@implicit", Cast2Ptr))
index 86a302939d0313e4104e6c1dcb96acfd373a34ea..ae258a3e335d8612120d725f6dd1b40bd991b2df 100644 (file)
@@ -619,7 +619,7 @@ PRAGMA_PUSH()
   if(!a.code->builtin) {
     register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
     mem += push;
-    *(m_uint*)  mem = push;mem += SZ_INT;
+    *(m_uint*)  mem = push; mem += SZ_INT;
     *(VM_Code*) mem = code; mem += SZ_INT;
     *(m_uint*)  mem = PC + VAL2; mem += SZ_INT;
     *(m_uint*) mem = a.code->stack_depth; mem += SZ_INT;
@@ -718,7 +718,7 @@ autoloop:
   m_vector_get(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT);
   goto autoloopcount;
 autoloopptr:
-  *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL));
+  *(m_bit**)(mem + VAL + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL));
 autoloopcount:
   *(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT))) - (*(m_uint*)(mem + VAL))++;
   reg += SZ_INT;