]> Nishi Git Mirror - gwion.git/commitdiff
:art: Use defined Gack
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 25 Sep 2019 16:40:42 +0000 (18:40 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 25 Sep 2019 16:40:42 +0000 (18:40 +0200)
18 files changed:
ast
include/gack.h
include/import.h
include/opcode.h
include/type.h
opcode.txt
src/emit/emit.c
src/lib/engine.c
src/lib/gack.c
src/lib/import.c
src/lib/object.c
src/lib/prim.c
src/lib/string.c
src/lib/tuple.c
src/oo/type.c
src/parse/scan1.c
src/vm/vm.c
tests/error/dtor_outside_class.gw

diff --git a/ast b/ast
index 37f69271d28e0e167e888b1e341b0000ff768641..bf16ee540da76d94a7d633a1419014a8b597efa1 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 37f69271d28e0e167e888b1e341b0000ff768641
+Subproject commit bf16ee540da76d94a7d633a1419014a8b597efa1
index bafbba2774d8c003eb96415d4e2e1b4b1392744c..d8a72e88a4b95f994b9fa257e9531ef7f37f4434 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __GACK
 #define __GACK
-ANN void gack(const Gwion, const m_bit*, const Instr);
+ANN void gack(const VM_Shred, const Instr);
 #endif
index d3bc83e97d27015a9888586f30fc0959bb0f36c6..d1d5285a77eac8174f8e32bb1f9a39064fc8dda3 100644 (file)
@@ -2,9 +2,10 @@
 #define __IMPORT
 #define DLARG_MAX 6
 
-typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred);
-typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh);
-typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh);
+typedef void (*f_xtor)(const M_Object, const m_bit*, const VM_Shred);
+typedef void (*f_mfun)(const M_Object, const m_bit*, const VM_Shred);
+typedef void (*f_sfun)(const m_bit*, const m_bit*, const VM_Shred);
+typedef void (*f_gack)(const Type, const m_bit*, const VM_Shred);
 typedef void (*f_xfun)();
 typedef struct Gwi_* Gwi;
 
@@ -12,6 +13,7 @@ typedef struct Gwi_* Gwi;
 #define SFUN(a) ANN void a(const M_Object o NUSED, const m_bit* RETURN NUSED, const VM_Shred shred NUSED)
 #define CTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
 #define DTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
+#define GACK(a) ANN2(2) void a(const Type t NUSED, const m_bit* VALUE NUSED, const VM_Shred shred NUSED)
 #define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
 #define OP_EMIT(a)  ANN Instr a(const Emitter emit NUSED, void* data NUSED)
 #ifdef GWION_BUILTIN
@@ -34,6 +36,7 @@ ANN VM* gwi_vm(const Gwi);
 ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type);
 ANN m_int gwi_add_type(const Gwi gwi, Type type);
 ANN m_int gwi_set_global_type(const Gwi gwi, const Type type, const type_enum te);
+ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d);
 ANN2(1,2)m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor);
 ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td);
 ANN m_int gwi_class_end(const Gwi gwi);
index 49fd830ac9841e37e916717f18ce6100a6e32a67..bda88115eefec3922798bfbc80c382e2cfdd347e 100644 (file)
@@ -171,6 +171,7 @@ enum {
   eGcAdd,
   eGcEnd,
   eGack,
+  eGack3,
   eDotTmplVal,
   eOP_MAX,
   eEOC,
@@ -346,6 +347,7 @@ enum {
 #define  GcAdd               (f_instr)eGcAdd
 #define  GcEnd               (f_instr)eGcEnd
 #define  Gack                (f_instr)eGack
+#define  Gack3               (f_instr)eGack3
 #define  DotTmplVal          (f_instr)eDotTmplVal
 #define  OP_MAX              (f_instr)eOP_MAX
 #define  EOC                 (f_instr)eEOC
index eb989a43a27ed48a8b371995adc15f0453954f5e..0b67d08ab961c7a4b41ee67fabd07d9f39812f29 100644 (file)
@@ -11,6 +11,7 @@ struct TypeInfo_ {
   } d;
   struct Vector_ contains;
   struct TupleForm_* tuple;
+  struct VM_Code_ *gack;
 };
 
 struct Type_ {
index eb027efef439907269e2d29a5b65489c0dbfe629..be86352c3572c3990374f49623e759aea7b48d16 100644 (file)
@@ -168,6 +168,7 @@ GcIni
 GcAdd
 GcEnd
 Gack
+Gack3
 DotTmplVal
 OP_MAX
 EOC
index 1f38acfa50cc9c1b6079be64520e9b84dc7b39e2..f1940cd438d0c6c4173e4382eecabf5585ec75d7 100644 (file)
@@ -560,17 +560,17 @@ ANN static m_bool prim_str(const Emitter emit, const Exp_Primary* prim) {
 
 ANN static m_bool prim_gack(const Emitter emit, const Exp_Primary* primary) {
   const Exp exp = primary->d.exp;
-  CHECK_BB(emit_exp(emit, exp, 0))
-  const Vector v = new_vector(emit->gwion->mp);
-  m_uint offset = 0;
-  Exp e = exp;
+  Exp e = exp, next = NULL;
   do {
-    vector_add(v, (vtype)e->type);
-    offset += e->type->size;
-  } while((e = e->next));
-  const Instr instr = emit_add_instr(emit, Gack);
-  instr->m_val = offset;
-  instr->m_val2 = (m_uint)v;
+    next = e->next;
+    e->next = NULL;
+    CHECK_BB(emit_exp(emit, e, 0))
+    const Instr instr = emit_add_instr(emit, Gack);
+    instr->m_val = (m_uint)e->type;
+    instr->m_val2 = emit_code_offset(emit);
+  } while((e = e->next = next));
+  if(!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack")))
+    emit_add_instr(emit, Gack3);
   return GW_OK;
 }
 
@@ -1747,6 +1747,9 @@ ANN static void emit_func_def_code(const Emitter emit, const Func func) {
   if(GET_FLAG(func->def, dtor)) {
     emit->env->class_def->nspc->dtor = func->code;
     ADD_REF(func->code)
+  } else if(func->def->base->xid == insert_symbol("@gack")) {
+    emit->env->class_def->e->gack = func->code;
+    ADD_REF(func->code)
   }
 }
 
index 42a45fc1fbffa8410de4ee7085fa42effe9fb3fe..128d2c398a209334d50fe3627cb37da32f27d69f 100644 (file)
 #include "lang_private.h"
 #include "specialid.h"
 
-static FREEARG(freearg_gack) {
-  free_vector(((Gwion)gwion)->mp, (Vector)instr->m_val2);
+static GACK(gack_class) {
+  printf("class(%p)", (*(Type*)VALUE)->e->d.base_type);
 }
 
+static GACK(gack_function) {
+  printf("%s", t->name);
+}
+
+static GACK(gack_fptr) {
+  const VM_Code code = *(VM_Code*)VALUE;
+  if(code)
+    printf("%s", code ? code->name : NULL);
+  else
+    printf("%s", t->name);
+}
+
+static GACK(gack_void) {
+  printf("(void)");
+}
+
+static GACK(gack_int) {
+  printf("%li", *(m_uint*)VALUE);
+}
+
+static GACK(gack_float) {
+  printf("%.4f", *(m_float*)VALUE);
+}
+
+// we where using m_complex
+static GACK(gack_complex) {
+  printf("#(%.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT));
+}
+static GACK(gack_polar) {
+  printf("%%(%.4f, %.4f*pi)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT) / M_PI);
+}
+static GACK(gack_vec3) {
+  printf("%%(%.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2));
+}
+static GACK(gack_vec4) {
+  printf("%%(%.4f, %.4f, %.4f, %.4f)", *(m_float*)VALUE, *(m_float*)(VALUE + SZ_FLOAT), *(m_float*)(VALUE + SZ_FLOAT*2), *(m_float*)(VALUE + SZ_FLOAT*3));
+}
 
 #define mk_class_instr(op, arg0, arg1, ...)                          \
 static INSTR(instr_class_##op) {                                     \
@@ -38,33 +75,42 @@ mk_class_instr(le, r, l)
 mk_class_instr(lt, r, l, && l != r)
 
 ANN static m_bool import_core_libs(const Gwi gwi) {
-  const Type t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL);
+  const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
   gwi->gwion->type[et_class] = t_class;
   GWI_BB(gwi_add_type(gwi, t_class))
+  CHECK_BB(gwi_gack(gwi, gwi->gwion->type[et_class], gack_class)) // not working yet
+  gwi->gwion->type[et_class] = t_class;
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
   SET_FLAG(t_class, abstract);
   const Type t_void  = gwi_mk_type(gwi, "void", 0, NULL);
+  CHECK_BB(gwi_gack(gwi, t_void, gack_void))
   GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
   const Type t_null  = gwi_mk_type(gwi, "@null",  SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_null, et_null))
   const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL);
+  GWI_BB(gwi_gack(gwi, t_function, gack_function))
   GWI_BB(gwi_set_global_type(gwi, t_function, et_function))
   const Type t_fptr = gwi_mk_type(gwi, "@func_ptr", SZ_INT, t_function);
+  GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
   GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
   const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, t_function);
   GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
   const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack))
   const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL);
+  CHECK_BB(gwi_gack(gwi, t_int, gack_int))
   GWI_BB(gwi_set_global_type(gwi, t_int, et_int))
   const Type t_float = gwi_mk_type(gwi, "float", SZ_FLOAT, NULL);
+  CHECK_BB(gwi_gack(gwi, t_float, gack_float))
   GWI_BB(gwi_set_global_type(gwi, t_float, et_float))
   const Type t_dur = gwi_mk_type(gwi, "dur", SZ_FLOAT, NULL);
+  CHECK_BB(gwi_gack(gwi, t_dur, gack_float))
   GWI_BB(gwi_add_type(gwi, t_dur))
   const Type t_time = gwi_mk_type(gwi, "time", SZ_FLOAT, NULL);
+  CHECK_BB(gwi_gack(gwi, t_time, gack_float))
   GWI_BB(gwi_add_type(gwi, t_time))
   const Type t_now = gwi_mk_type(gwi, "@now", SZ_FLOAT, t_time);
   GWI_BB(gwi_add_type(gwi, t_now))
@@ -73,12 +119,16 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   gwi_reserve(gwi, "now");
   const Type t_complex = gwi_mk_type(gwi, "complex", SZ_COMPLEX , NULL);
   gwi->gwion->type[et_complex] = t_complex;
+  CHECK_BB(gwi_gack(gwi, t_complex, gack_complex))
   const Type t_polar   = gwi_mk_type(gwi, "polar", SZ_COMPLEX , NULL);
   gwi->gwion->type[et_polar] = t_polar;
+  CHECK_BB(gwi_gack(gwi, t_polar, gack_polar))
   const Type t_vec3 = gwi_mk_type(gwi, "Vec3", SZ_VEC3, NULL);
   gwi->gwion->type[et_vec3] = t_vec3;
+  CHECK_BB(gwi_gack(gwi, t_vec3, gack_vec3))
   const Type t_vec4 = gwi_mk_type(gwi, "Vec4", SZ_VEC4, NULL);
   gwi->gwion->type[et_vec4] = t_vec4;
+  CHECK_BB(gwi_gack(gwi, t_vec4, gack_vec4))
   GWI_BB(import_object(gwi))
   const Type t_union = gwi_mk_type(gwi, "@Union", SZ_INT, gwi->gwion->type[et_object]);
   gwi->gwion->type[et_union] = t_union;
@@ -110,17 +160,13 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_oper_end(gwi, ">",  instr_class_gt))
   GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le))
   GWI_BB(gwi_oper_end(gwi, "<",  instr_class_lt))
-
-  register_freearg(gwi, Gack, freearg_gack);
   return GW_OK;
 }
 
 ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) {
   vm->gwion->env->name = "[builtin]";
-  struct Gwi_ gwi;
-  memset(&gwi, 0, sizeof(struct Gwi_));
-  gwi.gwion = vm->gwion;
-  gwi.loc = new_loc(vm->gwion->mp, 0);
+  struct YYLTYPE loc = {};
+  struct Gwi_ gwi = { .gwion=vm->gwion, .loc=&loc };
   GWI_BB(import_core_libs(&gwi))
   vm->gwion->env->name = "[imported]";
   for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
@@ -128,6 +174,5 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) {
     if(import && import(&gwi) < 0)
       env_reset(gwi.gwion->env);
   }
-  free_loc(vm->gwion->mp, gwi.loc);
   return GW_OK;
 }
index 55c1fbf000520e6f5a1452eddc6132e08d2655de..4d07a03cf3285a8c0e37817510ae0c294ee8cbca 100644 (file)
 #include "object.h"
 #include "instr.h"
 #include "gwion.h"
+#include "operator.h"
+#include "import.h"
 #include "gack.h"
 
-static void print_type(const Gwion gwion, const Type type) {
-  const m_bool is_func = isa(type, gwion->type[et_function]) > 0 && !is_fptr(gwion, type);
-  gw_out("(%s) ", is_func ? "@function" : type->name);
-  if(GET_FLAG(type, typedef)) {
-    gw_out(" aka ");
-    print_type(gwion, type->e->parent);
-  }
-}
-
-static inline void print_bool(const m_int i) {
-  gw_out("%s", i ? "true" : "false");
-}
-
-static inline void print_int(const m_int i) {
-  gw_out("%" INT_F "", i);
-}
-
-static inline void print_float(const m_float f) {
-  gw_out("%.4f", f);
-}
-
-static inline void print_complex(const m_complex c) {
-  gw_out("#(");
-  print_float(creal(c));
-  gw_out(", ");
-  print_float(cimag(c));
-  gw_out(")");
-}
-
-static inline void print_polar(const m_complex c) {
-  gw_out("%%(");
-  print_float(creal(c));
-  gw_out(", ");
-  print_float((m_float)cimag(c) / (m_float)M_PI);
-  gw_out("*pi)");
-}
-
-ANN static inline void print_vec(const m_bit* f, const m_uint size) {
-  gw_out("@(");
-  for(m_uint i = 0; i < size; i++) {
-    print_float(*(m_float*)(f + i * SZ_FLOAT));
-    if(i < size - 1)
-      gw_out(", ");
-  }
-  gw_out(")");
-}
-
-static inline void print_string1(const m_str str) {
-  gw_out("%s", str);
-}
-
-static inline void print_string(const M_Object obj) {
-  print_string1(obj ? STRING(obj) : "(null string)");
-}
-
-ANN2(1) static inline void print_object(const Gwion gwion, const Type type, const M_Object obj) {
-  if(isa(type, gwion->type[et_string]) > 0)
-    print_string(obj);
-  else
-    gw_out("%p", (void*)obj);
-}
-
-ANN static inline void print_func(const Gwion gwion,const Type type, const m_bit* stack) {
-  if(is_fptr(gwion, type) > 0 && type->e->d.func->def->base->tmpl) {
-    const Func f = *(Func*)stack;
-    gw_out("%s", f ? f->name : "(nil)");
-    return;
-  }
-  if(type->e->d.func) {
-    const VM_Code code = is_fptr(gwion, type) ?
-        *(VM_Code*)stack : type->e->d.func->code;
-    gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code);
-  } else // uncalled lambda
-    gw_out("%p", NULL);
-}
-
-ANN static void print_prim(const Gwion gwion, const Type type, const m_bit* stack) {
-  if(isa(type, gwion->type[et_bool]) > 0)
-    print_bool(*(m_int*)stack);
-  else if(isa(type, gwion->type[et_int]) > 0)
-    print_int(*(m_int*)stack);
-  else if(isa(type, gwion->type[et_complex]) > 0)
-    print_complex(*(m_complex*)stack);
-  else if(isa(type, gwion->type[et_polar]) > 0)
-    print_polar(*(m_complex*)stack);
-  else if(isa(type, gwion->type[et_vec3]) > 0)
-    print_vec(stack, 3);
-  else if(isa(type, gwion->type[et_vec4]) > 0)
-    print_vec(stack, 4);
-  else
-   print_float(*(m_float*)stack);
-}
-
-ANN void gack(const Gwion gwion, const m_bit* reg, const Instr instr) {
-  m_uint offset = instr->m_val;
-  const Vector v = (Vector)instr->m_val2;
-  const m_uint size = vector_size(v);
-  for(m_uint i = size + 1; --i;) {
-    const Type type = (Type)vector_at(v, size - i);
-    if(size == 1)
-      print_type(gwion, type);
-    if(isa(type, gwion->type[et_object]) > 0)
-      print_object(gwion, type, *(M_Object*)(reg-offset));
-    else if(isa(type, gwion->type[et_function]) > 0)
-      print_func(gwion, type, (reg-offset));
-    else if(type == gwion->type[et_class])
-      print_type(gwion, type);
-    else if(isa(type, gwion->type[et_class]) > 0)
-      print_type(gwion, type->e->d.base_type);
-    else if(isa(type, gwion->type[et_void]) > 0)
-      print_string1("void");
-    else
-      print_prim(gwion, type, (reg-offset));
-    offset -= type->size;
-  }
-  gw_out("\n");
+ANN void gack(const VM_Shred shred, const Instr instr) {
+  Type t = (Type)instr->m_val;
+  do {
+    if(t->e->gack) {
+      if(GET_FLAG(t->e->gack, builtin))
+        ((f_gack)t->e->gack->native_func)(t, (shred->reg - t->size), shred);
+      else {
+        shred->mem += instr->m_val2;
+        *(m_uint*)(shred->mem+ SZ_INT) = instr->m_val2 + SZ_INT;
+        *(VM_Code*)(shred->mem+ SZ_INT*2) = shred->code;
+        *(m_uint*)(shred->mem+ SZ_INT*3) = shred->pc;
+        *(m_uint*)(shred->mem+ SZ_INT*4) = SZ_INT;
+        shred->mem += SZ_INT*5;
+        *(M_Object*)(shred->mem)= *(M_Object*)(shred->reg - SZ_INT);
+        shred->code = t->e->gack;
+        shred->pc = 0;
+      }
+      return;
+    }
+  } while((t = t->e->parent));
 }
index 25b19b63e24493790006fca03905de5f12b83498..37601216f79b27f0ca6facebb0529168d81b2a84 100644 (file)
@@ -176,6 +176,17 @@ ANN /* static */ ID_List str2list(const Env env, const m_str path, m_uint* array
   return list;
 }
 
+ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
+  const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+  code->native_func = (m_uint)d;
+  type->e->gack = code;
+  return GW_OK;
+}
+
+ANN m_bool gwi_gack(const Gwi gwi, const Type type, const f_gack d) {
+  return mk_gack(gwi->gwion->mp, type, d);
+}
+
 ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
   VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
   const m_str name = type->name;
index d916859c5fe36d73a68772e227e0d3ecfd85aa17..daf0aad030306be5d11f7701668cf7d1995df65b 100644 (file)
@@ -221,8 +221,13 @@ static ID_CHECK(check_this) {
   return env->class_def;
 }
 
+static GACK(gack_object) {
+  printf("%p", *(M_Object*)VALUE);
+}
+
 GWION_IMPORT(object) {
   const Type t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
+  GWI_BB(gwi_gack(gwi, t_object, gack_object))
   gwi->gwion->type[et_object] = t_object;
   GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
   GWI_BB(gwi_class_end(gwi))
index 3cd9745fae5d3e7872d4c977b08d6b992a94cfec..d7dbf2a67f6045013f3347474de444a134d486b8 100644 (file)
@@ -71,12 +71,16 @@ static GWION_IMPORT(int_unary) {
   GWI_BB(gwi_oper_end(gwi, "--", int_post_dec))
   return GW_OK;
 }
+static GACK(gack_bool) {
+  printf("%s", *(m_uint*)VALUE ? "true" : "false");
+}
 
 static GWION_IMPORT(int_values) {
   GWI_BB(gwi_enum_ini(gwi, "bool"))
   GWI_BB(gwi_enum_add(gwi, "false", 0))
   GWI_BB(gwi_enum_add(gwi, "true", 1))
   const Type t_bool = gwi_enum_end(gwi);
+  GWI_BB(gwi_gack(gwi, t_bool, gack_bool))
   gwi->gwion->type[et_bool] = t_bool;
   GWI_BB(gwi_oper_ini(gwi, NULL, "int", "bool"))
   GWI_BB(gwi_oper_end(gwi,  "!", IntNot))
index 2ba94e2d5d30da490ff137da15e67c4b431dda27..cb6aeb93063368eeae0708471270a9e1eb7d6423 100644 (file)
@@ -181,8 +181,13 @@ ID_CHECK(check_funcpp) {
   return prim_str(env, (Exp_Primary * const)prim);
 }
 
+static GACK(gack_string) {
+  const M_Object obj = *(M_Object*)VALUE;
+  printf("%s", obj ? STRING(obj) : "(null string)");
+}
 GWION_IMPORT(string) {
   const Type t_string = gwi_mk_type(gwi, "string", SZ_INT, gwi->gwion->type[et_object]);
+  GWI_BB(gwi_gack(gwi, t_string, gack_string))
   GWI_BB(gwi_class_ini(gwi,  t_string, string_ctor, NULL))
   gwi->gwion->type[et_string] = t_string;
   gwi_item_ini(gwi, "int", "@data");
index 403ba60f796f441ee90d2be2a433827e80e0923f..c1df7b3e02ec0beb7946bdbc97deb89259d7391b 100644 (file)
@@ -94,6 +94,7 @@ ANN static void unpack_instr_decl(const Emitter emit, struct TupleEmit *te) {
       te->sz += value->type->size;
       sz += value->type->size;
       value->offset = emit_local(emit, value->type->size, 0);
+printf("value->offset %lu\n", value->offset);
     } else {
       sz += ((Type)vector_at(te->v, te->idx))->size;
       break;
@@ -202,7 +203,7 @@ static OP_EMIT(opem_at_tuple) {
   const Exp_Binary *bin = (Exp_Binary*)data;
   if(!(bin->rhs->exp_type == ae_exp_primary &&
       bin->rhs->d.exp_primary.primary_type == ae_primary_unpack)) {
-      return emit_add_instr(emit, ObjectAssign);
+    return emit_add_instr(emit, ObjectAssign);
   }
   const Exp e = bin->rhs->d.exp_primary.d.tuple.exp;
   const Vector v = &bin->lhs->type->e->tuple->types;
index 0038bcb911feef2c2c6bd868952a33537f010d9d..d2274beabd6bfb612be3aedb9d7739257aa8cf2b 100644 (file)
@@ -60,6 +60,7 @@ ANN Type type_copy(MemPool p, const Type type) {
   a->e->d.base_type   = type->e->d.base_type;
   a->array_depth   = type->array_depth;
   a->e->def           = type->e->def;
+  a->e->gack           = type->e->gack;
   return a;
 }
 
index c03be21f0a9983a678e1f00ab64fa2ffa65b211d..3c11b15295e53a025dd949e705ce506a6655b417 100644 (file)
@@ -357,8 +357,8 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
     CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
   if(tmpl_base(fdef->base->tmpl))
     return GW_OK;
-  if(GET_FLAG(fdef, dtor) && !env->class_def)
-    ERR_B(td_pos(fdef->base->td), _("dtor must be in class def!!"))
+  if(!env->class_def && (GET_FLAG(fdef, dtor) || fdef->base->xid == insert_symbol("@gack")))
+    ERR_B(td_pos(fdef->base->td), _("'%s' must be in class def!!"), s_name(fdef->base->xid))
   if(GET_FLAG(fdef, op) && env->class_def)
     SET_FLAG(fdef, static);
   struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func;
index 1f05477edd363aba1e7a88f762df157666f55f89..4da59501512697f06f47ad36f58d7b2f13ca40a7 100644 (file)
@@ -259,6 +259,8 @@ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED)
   else ADVANCE(); \
   IDISPATCH();
 
+#define VM_OUT shred->code = code; shred->reg = reg; shred->mem = mem; shred->pc = PC;
+
 __attribute__ ((hot, optimize("-O2")))
 ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
   static const void* dispatch[] = {
@@ -308,7 +310,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
     &&staticint, &&staticfloat, &&staticother,
     &&dotfunc, &&dotstaticfunc, &&pushstaticcode, &&pushstr,
     &&gcini, &&gcadd, &&gcend,
-    &&gack, &&regpushimm, &&other, &&eoc
+    &&gack, &&gack3, &&regpushimm, &&other, &&eoc
   };
   const Shreduler s = vm->shreduler;
   register VM_Shred shred;
@@ -567,10 +569,7 @@ timeadv:
   reg -= SZ_FLOAT;
   shredule(s, shred, *(m_float*)(reg-SZ_FLOAT));
   *(m_float*)(reg-SZ_FLOAT) += vm->bbq->pos;
-  shred->code = code;
-  shred->reg = reg;
-  shred->mem = mem;
-  shred->pc = PC;
+  VM_OUT
   break;
 setcode:
   a.code = *(VM_Code*)(reg-SZ_INT);
@@ -623,10 +622,7 @@ funcusrend:
   byte = bytecode = (code = a.code)->bytecode;
   SDISPATCH();
 funcmemberend:
-  shred->mem = mem;
-  shred->reg = reg;
-  shred->pc = PC;
-  shred->code = code;
+  VM_OUT
   {
     register const m_uint val = VAL;
     register const m_uint val2 = VAL2;
@@ -702,11 +698,9 @@ arrayaccess:
   if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
     gw_err(_("  ... at index [%" INT_F "]\n"), idx);
     gw_err(_("  ... at dimension [%" INT_F "]\n"), VAL);
-    shred->code = code;
-    shred->mem = mem;
-    shred->pc = PC;
+    VM_OUT
     exception(shred, "ArrayOutofBounds");
-    continue;
+    continue; // or break ?
   }
   DISPATCH()
 }
@@ -729,7 +723,7 @@ addref:
     ++a.obj->ref;
   DISPATCH()
 objassign:
-{
+{ // use a.obj ?
   register const M_Object tgt = **(M_Object**)(reg -SZ_INT);
   if(tgt) {
     --tgt->ref;
@@ -821,22 +815,24 @@ gcend:
     _release(a.obj, shred);
   DISPATCH()
 gack:
-  gack(vm->gwion, reg, (Instr)VAL);
-  DISPATCH()
+  VM_OUT
+  gack(shred, (Instr)VAL);
+  goto in;
+gack3:
+  gw_out("\n");
+  DISPATCH();
 other:
-shred->code = code;
-shred->reg = reg;
-shred->mem = mem;
-shred->pc = PC;
-      ((f_instr)VAL2)(shred, (Instr)VAL);
-if(!s->curr)break;
+  VM_OUT
+  ((f_instr)VAL2)(shred, (Instr)VAL);
+in:
+  if(!s->curr)
+    break;
   bytecode = (code = shred->code)->bytecode;
   reg = shred->reg;
   mem = shred->mem;
   PC_DISPATCH(shred->pc)
 eoc:
-  shred->code = code;
-  shred->mem = mem;
+  VM_OUT
   vm_shred_exit(shred);
     } while(s->curr);
   MUTEX_UNLOCK(s->mutex);
index e53249052026a8a1941f295f9f622ba21819cf10..612a8474c889b572b4af36d9005a534ad1bf3bd4 100644 (file)
@@ -1,2 +1,2 @@
-#! [contains] dtor must be in class def!!
+#! [contains] 'dtor' must be in class def!!
 dtor {}