]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Use emit_mod
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Wed, 10 Jun 2020 19:06:40 +0000 (21:06 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Wed, 10 Jun 2020 19:06:40 +0000 (21:06 +0200)
include/emit.h
include/modify_instr.h [new file with mode: 0644]
src/emit/emit.c
src/emit/modify_instr.c [new file with mode: 0644]
src/lib/object_op.c
src/parse/check.c
src/parse/scan1.c
src/vm/vm.c

index 1782caa1f63e2950e506e8608df7c9196a7203e9..df5602257c877821b126e7f1d4fce9350f28afe3 100644 (file)
@@ -40,7 +40,6 @@ ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((return
 ANN Code* emit_class_code(const Emitter, const m_str);
 ANN m_bool emit_array_extend(const Emitter, const Type, const Exp);
 ANN void emit_class_finish(const Emitter, const Nspc);
-ANN void emit_ext_ctor(const Emitter, const VM_Code);
 ANN void emit_union_offset(Decl_List, const m_uint);
 ANN2(1,2) m_bool emit_instantiate_object(const Emitter, const Type, const Array_Sub, const m_bool);
 ANN m_uint emit_code_offset(const Emitter emit);
diff --git a/include/modify_instr.h b/include/modify_instr.h
new file mode 100644 (file)
index 0000000..6a5a880
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __MODIFY_INSTR
+#define __MODIFY_INSTR
+typedef void (*instr_modifier)(m_bit *bytecode, m_bit *reg);
+
+ANN void emit_mod_recurs(const Emitter);
+ANN void emit_mod_func(const Emitter, const Func);
+ANN void emit_mod_ctor(const Emitter, const Type);
+#endif
index 87e7529ee3e5069e3b7f2783b54a0513246e906d..76b753d89e391d1daa7e6e4eb5c0d733d49debe5 100644 (file)
@@ -18,6 +18,7 @@
 #include "parser.h"
 #include "specialid.h"
 #include "vararg.h"
+#include "modify_instr.h"
 
 #undef insert_symbol
 #define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
@@ -161,9 +162,11 @@ ANN m_uint emit_local(const Emitter emit, const Type t) {
   return frame_local(emit->gwion->mp, emit->code->frame, t);
 }
 
-ANN static inline void maybe_ctor(const Emitter emit, const Type type) {
-  if(type->nspc && type->nspc->pre_ctor && !GET_FLAG(type, nonnull))
-    emit_ext_ctor(emit, type->nspc->pre_ctor);
+ANN void emit_ext_ctor(const Emitter emit, const Type t);
+
+ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
+  if(!GET_FLAG(t, nonnull) && GET_FLAG(t, ctor))
+    emit_ext_ctor(emit, t);
 }
 
 ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
@@ -243,11 +246,14 @@ ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Ty
   return info;
 }
 
-ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) {
+ANN void emit_ext_ctor(const Emitter emit, const Type t) {
   const Instr cpy = emit_add_instr(emit, Reg2Reg);
   cpy->m_val2 = -SZ_INT;
-  const Instr set_code = regseti(emit, (m_uint)code);
-  set_code->m_val2 = SZ_INT;
+  if(t->nspc->pre_ctor) {
+    const Instr set_code = regseti(emit, (m_uint)t->nspc->pre_ctor);
+    set_code->m_val2 = SZ_INT;
+  } else
+    emit_mod_ctor(emit, t);
   const m_uint offset = emit_code_offset(emit);
   const Instr regset = regseti(emit, offset);
   regset->m_val2 = SZ_INT *2;
@@ -600,7 +606,7 @@ ANN static void decl_expand(const Emitter emit, const Type t) {
 
 ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, const uint emit_addr) {
   emit->code->frame->curr_offset += t->size + SZ_INT;
-  emit_ext_ctor(emit, t->nspc->pre_ctor);
+  emit_ext_ctor(emit, t);
   if(!emit_addr)
     decl_expand(emit, t);
   emit->code->frame->curr_offset -= t->size + SZ_INT;
@@ -1040,7 +1046,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
     if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
       if(emit->env->func != f)
         CHECK_BO(emit_template_code(emit, f))
-      else {
+      else { // recursive function. (maybe should be used only for global funcs)
         const Instr back = (Instr) vector_size(&emit->code->instr) ?
             (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm);
         back->opcode = ePushStaticCode;
@@ -1078,17 +1084,15 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
     const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
     instr->m_val = val;
     instr->m_val2 = val2;
-  } else if(f != emit->env->func && !f->code&& ! is_fptr(emit->gwion, f->value_ref->type)){
+  } else if(f != emit->env->func && !f->code && !is_fptr(emit->gwion, f->value_ref->type)){
     /* not yet emitted static func */
     if(f->value_ref->from->owner_class) {
       const Instr instr = vector_size(&emit->code->instr) ?
         (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, PushStaticCode);
       assert(instr->opcode == ePushStaticCode);
       instr->opcode = eRegPushImm;
-    } else {
-      const Instr pushcode = emit_add_instr(emit, PushStaticCode);
-      pushcode->m_val = (m_uint)f;
-    }
+    } else
+      emit_mod_func(emit, f);
   }
   const m_uint offset = emit_code_offset(emit);
   regseti(emit, offset);
@@ -2042,9 +2046,9 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   const Type t = cdef->base.type;
   if(GET_FLAG(t, emit))
     return GW_OK;
+  SET_FLAG(t, emit);
   if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
     CHECK_BB(cdef_parent(emit, cdef))
-  SET_FLAG(t, emit);
   nspc_allocdata(emit->gwion->mp, t->nspc);
   if(cdef->body) {
     emit_class_code(emit, t->name);
diff --git a/src/emit/modify_instr.c b/src/emit/modify_instr.c
new file mode 100644 (file)
index 0000000..488f565
--- /dev/null
@@ -0,0 +1,52 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "instr.h"
+#include "emit.h"
+
+// should be in vm.h
+#define VAL (*(m_uint*)(byte + SZ_INT))
+#define FVAL (*(m_float*)(byte + SZ_INT))
+#define VAL2 (*(m_uint*)(byte + SZ_INT*2))
+/*
+ANN static void set_recurs(m_bit *byte, m_bit **reg) {
+  *(m_bit*)byte = eRegPushImm;
+  VAL = (*(m_uint*)(*reg-SZ_INT) = );
+  VAL2 = -SZ_INT;
+// copy from vm_code
+}
+*/
+
+ANN static void set_func(m_bit *byte, m_bit **reg) {
+  *(m_bit*)byte = eRegSetImm;
+  VAL = (*(m_uint*)(*reg-SZ_INT) = (m_uint)((Func)VAL)->code);
+  VAL2 = -SZ_INT;
+// copy from vm_code
+}
+
+ANN static void set_ctor(m_bit *byte, m_bit *reg) {
+  *(m_bit*)byte = eRegSetImm;
+  VAL = (*(m_uint*)(reg+SZ_INT) = (m_uint)((Type)VAL)->nspc->pre_ctor);
+  VAL2 = SZ_INT;
+}
+
+ANN void emit_mod_recurs(const Emitter emit) {
+  const Instr instr = vector_size(&emit->code->instr) ?
+    (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm);
+  instr->opcode = ePushStaticCode;
+  instr->m_val = 0;
+}
+
+ANN void emit_mod_func(const Emitter emit, const Func f) {
+  const Instr instr = emit_add_instr(emit, PushStaticCode);
+  instr->m_val = (m_uint)f;
+  instr->m_val2 = (m_uint)set_func;
+}
+
+ANN void emit_mod_ctor(const Emitter emit, const Type t) {
+  const Instr instr = emit_add_instr(emit, PushStaticCode);
+  instr->m_val = (m_uint)t;
+  instr->m_val2 = (m_uint)set_ctor;
+}
index 1ae6d75991d8d95c6442bde3d6973be44221cbbf..7f9e3188d395333d6aa2457503881817cb2c480c 100644 (file)
@@ -264,9 +264,12 @@ OP_EMIT(opem_object_dot) {
       CHECK_BO(emit_exp(emit, member->base))
       emit_struct_data(emit, value, exp_getvar(exp_self(member)));
     }
-  }
-  else if(GET_FLAG(value, static))
+  } else if(GET_FLAG(value, static))
     emit_dot_static_import_data(emit, value, exp_getvar(exp_self(member)));
+  else { // member type
+    const Instr instr = emit_add_instr(emit, RegPushImm);
+    instr->m_val = (m_uint)value->type;
+  }
   return (Instr)GW_OK;
 }
 
index 74f902b58cb900aa4f6dce677cfc19edb426240c..e3f1adca92373c3c8e48ec3bfc36c8eb6cb57451 100644 (file)
@@ -1406,8 +1406,10 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
     CHECK_BB(cdef_parent(env, cdef))
   if(!GET_FLAG(cdef, struct))
     inherit(t);
-  if(cdef->body)
+  if(cdef->body) {
     CHECK_BB(env_body(env, cdef, check_section))
+    SET_FLAG(t, ctor);
+  }
   SET_FLAG(t, valid);
   return GW_OK;
 }
index 1c700c4793183b2ff2495697b4ea7eff798c9f71..6ae616484803a2bd09878027bb08729f0916cda3 100644 (file)
@@ -28,20 +28,10 @@ ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
   return envset_run(&es, t);
 }
 
-ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type t) {
-  const Type base = get_type(t);
-  if(!GET_FLAG(td, ref) && env->class_def && !env->scope->depth &&
-          base == env->class_def) {
-    ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"),
-       t->name, t == env->class_def ? "itself" : env->class_def->name);
-  }
-  return GW_OK;
-}
-
 ANN static Type scan1_type(const Env env, Type_Decl* td) {
   DECL_OO(const Type, type, = known_type(env, td))
   const Type t = get_type(type);
-  if(!env->func && env->class_def)
+  if(!env->func && env->class_def && !GET_FLAG(td, ref))
     CHECK_BO(type_cyclic(env, t, td))
   if(!GET_FLAG(t, scan1) && t->e->def)
     CHECK_BO(ensure_scan1(env, t))
@@ -50,8 +40,6 @@ ANN static Type scan1_type(const Env env, Type_Decl* td) {
 
 ANN static Type void_type(const Env env, Type_Decl* td) {
   DECL_OO(const Type, type, = scan1_type(env, td))
-  if(isa(type, env->gwion->type[et_compound]) > 0)
-    CHECK_BO(type_recursive(env, td, type))
   if(type->size)
     return type;
   ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
index 349f959c1a395f86974106983b6cbdaaa4c423d2..06751199a5e5fdfa211aa8000b62b2e9ef10f14e 100644 (file)
@@ -14,7 +14,7 @@
 #include "map_private.h"
 #include "gack.h"
 #include "array.h"
-
+#include "modify_instr.h"
 
 static inline uint64_t splitmix64_stateless(uint64_t index) {
   uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15));
@@ -837,10 +837,8 @@ PRAGMA_PUSH()
   *(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code;
 PRAGMA_POP()
   DISPATCH()
-pushstaticcode:
-  *(m_bit*)byte = eRegSetImm;
-  VAL = (*(m_uint*)(reg-SZ_INT) = (m_uint)((Func)VAL)->code);
-  VAL2 = -SZ_INT;
+pushstaticcode: // TODO: use external instr
+  ((instr_modifier)VAL2)(byte, reg);
   DISPATCH()
 gcini:
   vector_add(&shred->gc, 0);