]> Nishi Git Mirror - gwion.git/commitdiff
Prepare (#236)
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 9 Jan 2022 13:40:48 +0000 (14:40 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Jan 2022 13:40:48 +0000 (14:40 +0100)
* :art: Use prepared bytecode

* :art: Use prepared bytecode

* :bug: Fix object destructor

* :art: :bomb: :bug: Fix object_dtor and clean a few things

* Fix repl (compilation at least)

* Fix repl (add wait time)

* :art: unbork Makefile

* :bug: Fix 1 channel dac

* :art: add ability to force load plugins

* :art: add ability to force load plugins (fix)

* :art: add ability to force load plugins (fix)

* :book: start Repl doc

* :art: Darling clean the pool

13 files changed:
Makefile
include/instr.h
include/vm.h
plug
src/arg.c
src/emit/emit.c
src/lib/array.c
src/lib/instr.c
src/lib/object.c
src/lib/ugen.c
src/vm/vm.c
src/vm/vm_code.c
util

index 1424f0ba929d5229bfe1908d36f2850df3a9330f..b89cc7a9bb169bb36faeacd74c405604ad7eb2a7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -83,13 +83,13 @@ util/include/generated.h:
 util/libtermcolor/libtermcolor.a:
        @+${MAKE} BUILD_ON_WINDOWS=${BUILD_ON_WINDOWS} -s -C util/libtermcolor static
 
-util/libgwion_util.a:
+util/libgwion_util.a: util/include/generated.h
        @+GWION_PACKAGE= ${MAKE} -s -C util
 
 util: util/libgwion_util.a
        @(info build util)
 
-ast/libgwion_ast.a:
+ast/libgwion_ast.a: util/libgwion_util.a
        @+GWION_PACKAGE= ${MAKE} -s -C ast
 
 libcmdapp/libcmdapp.a:
index e61921201c826fba6eac83e82e4cf0749faff472..03a10109a9a1b53e43a5ba71ebabd6f6bb9d5a85 100644 (file)
@@ -33,8 +33,7 @@ struct Instr_ {
   };
   void (*execute)(const VM_Shred shred, const Instr instr);
 };
-#define BYTECODE_SZ                                                            \
-  ((2 * sizeof(unsigned)) + sizeof(struct Instr_) - SZ_INT * 2)
+#define BYTECODE_SZ (SZ_INT * 4)
 
 ANN void free_instr(const Gwion, const Instr);
 INSTR(EOC);
index c5ff5ac637c68dcdbbfa3cb2fae050e41d0abfd2..869559ec94756e3b753a609491203ec45dde72b8 100644 (file)
@@ -26,6 +26,7 @@ struct VM_Code_ {
   struct M_Vector_ live_values;
   uint16_t         stack_depth;
   uint16_t         ref;
+  bool             is_prepared;
   bool             builtin;
   bool             callback;
   bool             is_memoize;
@@ -122,7 +123,10 @@ vm_shred_exit(const VM_Shred shred) {
 }
 void free_vm_shred(const VM_Shred shred) __attribute__((hot, nonnull));
 
-ANN void vm_run(const VM *vm) __attribute__((hot));
+void vm_prepare(const VM *vm, m_bit*) __attribute__((hot));
+ANN static inline void vm_run(const VM *vm) {
+  vm_prepare(vm, NULL);
+}
 ANEW VM * new_vm(MemPool, const bool);
 ANN void  vm_lock(VM const *);
 ANN void  vm_unlock(VM const *);
diff --git a/plug b/plug
index e53662dbeacd2f02e7c8507323a21d659c2dbc70..4387f4fe3ac0326476225fa6190dc428e3303f41 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit e53662dbeacd2f02e7c8507323a21d659c2dbc70
+Subproject commit 4387f4fe3ac0326476225fa6190dc428e3303f41
index cce495dbb94eb7de2be5912a842390bcb19b1dee..46d1c5d433a592b0a64c817dfbe59fc50295d618 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -14,6 +14,7 @@
 enum {
   CONFIG,
   PLUGIN,
+  LOAD_PLUGIN,
   MODULE,
   LOOP,
   PASS,
@@ -57,6 +58,7 @@ ANN static m_str plug_dir(void) {
 enum arg_type {
   ARG_FILE,
   ARG_STDIN,
+  ARG_LOAD_PLUGIN,
   ARG_DEFINE,
   ARG_UNDEF,
   ARG_INCLUDE,
@@ -114,6 +116,13 @@ ANN void arg_compile(const Gwion gwion, Arg *arg) {
     case ARG_STDIN:
       compile_file(gwion, "stdin", stdin);
       break;
+    case ARG_LOAD_PLUGIN:
+{
+      char c[1024];
+      sprintf(c, "#import %s\n", (m_str)VPTR(v, ++i));
+      compile_string(gwion, "<command-line>", c);
+      break;
+}
     case ARG_DEFINE:
       pparg_add(gwion->ppa, (m_str)VPTR(v, ++i));
       break;
@@ -174,6 +183,8 @@ static void setup_options(cmdapp_t *app, cmdopt_t *opt) {
              "number of input channel", &opt[NINPUT]);
   cmdapp_set(app, 'o', "output", CMDOPT_TAKESARG, NULL,
              "number of output channel", &opt[NOUTPUT]);
+  cmdapp_set(app, 'P', "plugin", CMDOPT_TAKESARG, NULL, "(force-)load a plugin",
+             &opt[LOAD_PLUGIN]);
   cmdapp_set(app, 'D', "define", CMDOPT_TAKESARG, NULL, "define a macro",
              &opt[DEFINE]);
   cmdapp_set(app, 'U', "undef", CMDOPT_TAKESARG, NULL, "undefine a macro",
@@ -271,6 +282,10 @@ static void myproc(void *data, cmdopt_t *option, const char *arg) {
     case '\0':
       vector_add(&_arg->add, (vtype)ARG_STDIN);
       break;
+    case 'P':
+      vector_add(&_arg->add, (vtype)ARG_LOAD_PLUGIN);
+      vector_add(&_arg->add, (vtype)option->value);
+      break;
     case 'c':
       if (!strcmp(option->value, "never"))
         _arg->color = COLOR_NEVER;
index ea2ea83191b34333816b8334cdd861365700d0e5..22c2ff2aee6451ba929701d64bee2d2b49490867 100644 (file)
@@ -2843,7 +2843,8 @@ ANN static void me_ret(MemoizeEmitter *me) {
   const Instr instr =
       emit_regpushmem(me->emit, me->fdef->base->ret_type->size, false);
   instr->m_val = (me->offset + SZ_INT) * 2;
-  emit_add_instr(me->emit, FuncReturn);
+//  emit_add_instr(me->emit, FuncReturn);
+vector_add(&me->emit->code->stack_return, (vtype)emit_add_instr(me->emit, Goto));
 }
 
 ANN static m_bool me_run(MemoizeEmitter *me, const m_uint pc) {
index b26d4a2773f97def180a38240f7d2cd584a87c9d..2c5a9a8917dcc74357c785ccb70bbe8242e59062 100644 (file)
@@ -373,27 +373,27 @@ static OP_EMIT(opem_array_access) {
   return exp ? emit_array_access(emit, info) : GW_ERROR;
 }
 
-static m_bit                 map_byte[BYTECODE_SZ * 4];
+static m_bit                 map_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ map_run_code = {.name     = "map_run_code",
                                              .bytecode = map_byte};
 
-static m_bit                 compactmap_byte[BYTECODE_SZ * 4];
+static m_bit                 compactmap_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ compactmap_run_code = {
     .name = "compactmap_run_code", .bytecode = compactmap_byte};
 
-static m_bit                 filter_byte[BYTECODE_SZ * 4];
+static m_bit                 filter_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ filter_run_code = {.name     = "filter_run_code",
                                                 .bytecode = filter_byte};
 
-static m_bit                 count_byte[BYTECODE_SZ * 4];
+static m_bit                 count_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ count_run_code = {.name     = "count_run_code",
                                                .bytecode = count_byte};
 
-static m_bit                 foldl_byte[BYTECODE_SZ * 4];
+static m_bit                 foldl_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ foldl_run_code = {.name     = "foldl_run_code",
                                                .bytecode = foldl_byte};
 
-static m_bit                 foldr_byte[BYTECODE_SZ * 4];
+static m_bit                 foldr_byte[BYTECODE_SZ * 5];
 static const struct VM_Code_ foldr_run_code = {.name     = "foldr_run_code",
                                                .bytecode = foldr_byte};
 
@@ -779,14 +779,17 @@ ANN static void prepare_run(m_bit *const byte, const f_instr ini,
   *(unsigned *)(byte + BYTECODE_SZ * 2)             = eOverflow;
   *(unsigned *)(byte + BYTECODE_SZ * 3)             = eOP_MAX;
   *(f_instr *)(byte + BYTECODE_SZ * 3 + SZ_INT * 2) = end;
+  *(unsigned *)(byte + BYTECODE_SZ * 4)             = eEOC;
 }
 
 ANN static void prepare_map_run(m_bit *const byte, const f_instr end) {
   prepare_run(byte, map_run_ini, end);
+  vm_prepare(NULL, byte);
 }
 
 ANN static void prepare_fold_run(m_bit *const byte, const f_instr ini) {
   prepare_run(byte, ini, fold_run_end);
+  vm_prepare(NULL, byte);
 }
 
 GWION_IMPORT(array) {
index 7d32b2ddc722b139d88f701c707e57a1a028b22f..0a138a0677850e3e1b5ee4deb4233118efde8021 100644 (file)
@@ -122,17 +122,21 @@ INSTR(DotTmpl) {
 #define FVAL (*(m_float *)(byte + SZ_INT))
 #define VAL2 (*(m_uint *)(byte + SZ_INT * 2))
 #define BYTE(a)                                                                \
-  m_bit *byte    = shred->code->bytecode + (shred->pc - 1) * SZ_INT * 3;       \
-  *(m_bit *)byte = a;
+  m_bit *byte    = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ;       \
+  *(m_uint *)byte = a;
 
 INSTR(SetFunc) {
-  BYTE(eRegPushImm)
+//  BYTE(eRegPushImm)
+  m_bit *byte    = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ;       \
+  *(m_uint *)byte = instr->opcode;
+  instr->opcode = eRegPushImm;
   const Func f = (Func)instr->m_val;
   VAL = *(m_uint *)(shred->reg) = (m_uint)f->code;
   shred->reg += SZ_INT;
 }
 
 INSTR(SetRecurs) {
+exit(4);
   BYTE(eRegPushImm)
   VAL = *(m_uint *)(shred->reg) = (m_uint)shred->code;
   shred->reg += SZ_INT;
@@ -147,7 +151,10 @@ INSTR(SetCtor) {
 
 INSTR(fast_except) {
   if(*(m_uint*)REG((m_int)instr->m_val)) {
-    BYTE(eNoOp)
+//    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");
 }
index 8a9aad0823f96f5ed002a1fb4c350b50b772ae88..6db3f0606d30b911e85f2e2d4407a3934ff04b1a 100644 (file)
@@ -1,5 +1,3 @@
-#include <stdlib.h>
-#include <string.h>
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
@@ -44,16 +42,6 @@ ANN static void user_dtor(const M_Object o, const VM_Shred shred, const Type t)
   ++sh->info->me->ref;
 }
 
-static DTOR(object_dtor) {
-  free_object(shred->info->mp, o);
-}
-
-ANN static inline Type next_type(Type t) {
-  do if(t->nspc) return t;
-  while((t = t->info->parent));
-  return NULL;
-}
-
 ANN static inline void release_not_union(const m_bit *data, const VM_Shred shred, const Scope s) {
   const Map m = &s->map;
   for(m_uint i = map_size(m) + 1; --i;) {
@@ -65,9 +53,10 @@ ANN static inline void release_not_union(const m_bit *data, const VM_Shred shred
 
 ANN static void do_release(const M_Object o,
                                         const VM_Shred shred, const Type t) {
-  const Type next = next_type(t);
-  if(!next)
+  if(!t->nspc->offset) {
+    free_object(shred->info->mp, o);
     return;
+  }
   if (!tflag(t, tflag_union))
     release_not_union(o->data, shred, t->nspc->info->value);
   if (tflag(t, tflag_dtor)) {
@@ -93,7 +82,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
 }
 
 ANN void free_object(MemPool p, const M_Object o) {
-  mp_free2(p, o->type_ref->nspc->offset, o);
+  mp_free2(p, sizeof(struct M_Object_) + o->type_ref->nspc->offset, o);
 }
 
 static ID_CHECK(opck_this) {
@@ -127,9 +116,6 @@ GWION_IMPORT(object) {
   const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, "@Compound");
   gwi_set_global_type(gwi, t_object, et_object);
   t_object->nspc = new_nspc(gwi->gwion->mp, "Object");
-  t_object->nspc->dtor = new_vmcode(gwi->gwion->mp, NULL, NULL, "Object", SZ_INT, true, false);
-  t_object->nspc->dtor->native_func = (m_uint)object_dtor;
-  t_object->tflag |= tflag_dtor;
   struct SpecialId_ spid = {.ck = opck_this, .em = opem_this, .is_const = 1};
   gwi_specialid(gwi, "this", &spid);
   return GW_OK;
index 75933625ac8204de5e896636d3cc704e967dc3a4..d0e1f4250ab0e2d7be007fe4d87fe329d960dd4b 100644 (file)
@@ -377,10 +377,24 @@ static GWION_IMPORT(global_ugens) {
   struct ugen_importer imp_hole = {vm, compute_mono, "blackhole", 1};
   const UGen           hole     = add_ugen(gwi, &imp_hole);
   struct ugen_importer imp_dac  = {vm, dac_tick, "dac", vm->bbq->si->out};
-  const UGen           dac      = add_ugen(gwi, &imp_dac);
+
+  // dac needs to have *multi*
+  const M_Object dac  = new_M_UGen(gwi->gwion);
+  const UGen     u  = UGEN(dac);
+    u->connect.multi         = mp_calloc(gwi->gwion->mp, ugen_multi);
+    u->connect.multi->n_in   = vm->bbq->si->out;
+    u->connect.multi->n_out  = vm->bbq->si->out;
+    u->connect.multi->n_chan = vm->bbq->si->out;
+    assign_channel(gwi->gwion, u);
+  ugen_gen(vm->gwion, u, dac_tick, (void *)vm, 0);
+  vector_add(&vm->ugen, (vtype)u);
+  gwi_item_ini(gwi, "UGen", "dac");
+  gwi_item_end(gwi, ae_flag_const, obj, dac);
+  ugen_connect(u, hole);
+
+
   struct ugen_importer imp_adc  = {vm, adc_tick, "adc", vm->bbq->si->in};
   (void)add_ugen(gwi, &imp_adc);
-  ugen_connect(dac, hole);
   SET_FLAG(gwi->gwion->type[et_ugen], abstract);
   return GW_OK;
 }
index 507dfab051ed8b25c6e8374091c95909f6eab49e..26605895773d6bfab190da5253fb7262092f2e16 100644 (file)
@@ -81,7 +81,6 @@ ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect, co
   if (start > shred->pc) return true;
   const uint16_t pc = find_pc(shred, effect, size);
   if (!pc) // outside of a try statement
-//    return true;
     return false;
   // we should clean values here
   shred->reg = // restore reg
@@ -90,7 +89,6 @@ ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect, co
   shred->pc = pc; // VKEY(m, i);
   vector_pop(&shred->info->frame);
   vector_pop(&shred->info->frame);
-//  return false;
   return true;
 }
 
@@ -276,14 +274,15 @@ ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code,
 #define handle(a, b) VM_OUT handle(a, b);
 #define TEST0(t, pos)                                                          \
   if (!*(t *)(reg - pos)) {                                                    \
-/*    shred->pc = PC;*/                                                            \
     handle(shred, "ZeroDivideException");                                      \
     break;                                                                     \
   }
 
-#define ADVANCE() byte += BYTECODE_SZ;
+//#define ADVANCE() { byte += BYTECODE_SZ; shred->pc++;}
+#define ADVANCE() byte += BYTECODE_SZ
 
-#define SDISPATCH() goto *dispatch[*(m_bit *)byte];
+//#define SDISPATCH() goto *dispatch[*(m_bit *)byte];
+#define SDISPATCH() goto **(void***)byte;
 #define IDISPATCH()                                                            \
   {                                                                            \
     VM_INFO;                                                                   \
@@ -292,23 +291,23 @@ ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code,
 
 #define SET_BYTE(pc) (byte = bytecode + (pc)*BYTECODE_SZ)
 
-#define PC_DISPATCH(pc)                                                        \
-  SET_BYTE((pc));                                                              \
+#define PC_DISPATCH(_pc)                                                        \
+  SET_BYTE((_pc));                                                            \
+/*  shred->pc = _pc + 1;*/\
   IDISPATCH();
 
 #define DISPATCH()                                                             \
   ADVANCE();                                                                   \
   IDISPATCH();
 
-#define ADVANCE() byte += BYTECODE_SZ;
-
 #define ADISPATCH()                                                            \
   {                                                                            \
     ADVANCE();                                                                 \
     SDISPATCH();                                                               \
   }
 
-#define PC (*(unsigned *)(byte + 1))
+#define PC (*(m_uint *)(byte + SZ_INT*3))
+//#define PC (shred->pc)
 
 #define OP(t, sz, op, ...)                                                     \
   reg -= sz;                                                                   \
@@ -415,20 +414,19 @@ _Pragma(STRINGIFY(COMPILER diagnostic push)) \
 _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED)
 #define PRAGMA_POP() _Pragma(STRINGIFY(COMPILER diagnostic pop))
 
-#define VMSZ (SZ_INT > SZ_FLOAT ? SZ_INT : SZ_FLOAT)
-
-#define VAL   (*(m_uint *)(byte + VMSZ))
-#define IVAL  (*(m_int *)(byte + VMSZ))
-#define FVAL  (*(m_float *)(byte + VMSZ))
+#define VAL   (*(m_uint *)(byte + SZ_INT))
+#define IVAL  (*(m_int *)(byte + SZ_INT))
+#define FVAL  (*(m_float *)(byte + SZ_INT))
 #define VAL2  (*(m_uint *)(byte + SZ_INT + SZ_INT))
 #define IVAL2  (*(m_int *)(byte + SZ_INT + SZ_INT))
 #define SVAL  (*(uint16_t *)(byte + SZ_INT + SZ_INT))
 #define SVAL2 (*(uint16_t *)(byte + SZ_INT + SZ_INT + sizeof(uint16_t)))
 
 #define BRANCH_DISPATCH(check)                                                 \
-  if (check)                                                                   \
+  if (check)                                                                   \
     SET_BYTE(VAL);                                                             \
-  else                                                                         \
+    shred->pc = VAL + 1;\
+  } else                                                                         \
     ADVANCE();                                                                 \
   IDISPATCH();
 
@@ -438,8 +436,8 @@ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED)
   shred->mem  = mem;                                                           \
   shred->pc   = PC;
 
-__attribute__((hot)) ANN void
-vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
+__attribute__((hot)) void
+vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
   static const void *dispatch[] = {
       &&regsetimm, &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
       &&regpushmem, &&regpushmemfloat, &&regpushmemother, &&regpushmemaddr,
@@ -488,24 +486,23 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       &&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline,
       &&debugvalue, &&debugpush, &&debugpop, &&eoc, &&unroll2, &&other,
       &&regpushimm};
-  const Shreduler   s = vm->shreduler;
-  register VM_Shred shred;
-  register m_bit    next;
 
+  if(!prepare_code) {
+    PRAGMA_PUSH()
+  const Shreduler   s = vm->shreduler;
+  VM_Shred shred;
   while ((shred = shreduler_get(s))) {
-    register VM_Code code     = shred->code;
-    register m_bit * bytecode = code->bytecode;
-    register m_bit * byte     = bytecode + shred->pc * BYTECODE_SZ;
-    register m_bit * reg      = shred->reg;
-    register m_bit * mem      = shred->mem;
-    register union {
+    VM_Code code     = shred->code;
+    m_bit * bytecode = code->bytecode;
+    m_bit * byte     = bytecode + shred->pc * BYTECODE_SZ;
+    m_bit * reg      = shred->reg;
+    m_bit * mem      = shred->mem;
+    m_bit   next;
+    union {
       M_Object obj;
       VM_Code  code;
     } a;
-    PRAGMA_PUSH()
-    register VM_Shred child;
-    PRAGMA_POP()
-//    MUTEX_LOCK(s->mutex);
+    VM_Shred child;
     do {
       SDISPATCH();
     regsetimm:
@@ -918,7 +915,6 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     }
       DISPATCH();
     setcode:
-      PRAGMA_PUSH()
       a.code = *(VM_Code *)(reg - SZ_INT);
       if (!a.code->builtin) {
         register const uint push =
@@ -931,7 +927,6 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
         mem += *(m_uint *)reg;
         next = eFuncMemberEnd;
       }
-      PRAGMA_POP()
     regmove:
       reg += IVAL;
       DISPATCH();
@@ -943,17 +938,12 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     overflow:
       if (overflow_(mem + VAL2, shred)) {
-//        shred->pc = PC;
         handle(shred, "StackOverflow");
         continue;
       }
-      PRAGMA_PUSH()
       goto *dispatch[next];
-      PRAGMA_POP()
     funcusrend:
-      PRAGMA_PUSH()
       byte = bytecode = (code = a.code)->bytecode;
-      PRAGMA_POP()
       SDISPATCH();
     funcusrend2:
       byte = bytecode;
@@ -975,13 +965,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       child = init_fork_shred(shred, (VM_Code)VAL, (Type)VAL2);
       DISPATCH()
     sporkfunc:
-      PRAGMA_PUSH()
       //  LOOP_OPTIM
       for (m_uint i = 0; i < VAL; i += SZ_INT)
         *(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2);
       child->reg += VAL;
       DISPATCH()
-      PRAGMA_POP()
     sporkmemberfptr:
       for (m_uint i = SZ_INT; i < VAL; i += SZ_INT)
         *(m_uint *)(child->reg + i) = *(m_uint *)(reg - VAL + i);
@@ -997,9 +985,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     sporkend:
       assert(!VAL); // spork are not mutable
-      PRAGMA_PUSH()
       *(M_Object *)(reg - SZ_INT) = child->info->me;
-      PRAGMA_POP()
       DISPATCH()
     brancheqint:
       reg -= SZ_INT;
@@ -1057,15 +1043,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     }
     arrayget:
-      PRAGMA_PUSH()
       m_vector_get(ARRAY(a.obj), *(m_int *)(reg + VAL), (reg + IVAL2));
-      PRAGMA_POP()
       DISPATCH()
     arrayaddr:
-      PRAGMA_PUSH()
       *(m_bit **)(reg + IVAL2) =
           m_vector_addr(ARRAY(a.obj), *(m_int *)(reg + VAL));
-      PRAGMA_POP()
       DISPATCH()
     newobj:
       *(M_Object *)reg = new_object(vm->gwion->mp, (Type)VAL2);
@@ -1132,11 +1114,9 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     dotother:
       //  LOOP_OPTIM
-      PRAGMA_PUSH()
       for (m_uint i = 0; i <= VAL2; i += SZ_INT)
         *(m_uint *)(reg + i - SZ_INT) =
             *(m_uint *)(((*(M_Object *)(reg - SZ_INT))->data + VAL) + i);
-      PRAGMA_POP()
       reg += VAL2 - SZ_INT;
       DISPATCH()
     dotaddr:
@@ -1170,10 +1150,8 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     }
     unionother : {
       UNION_CHECK
-      PRAGMA_PUSH()
       for (m_uint i = 0; i <= VAL2; i += SZ_INT)
         *(m_uint *)(reg + i - SZ_INT) = *(m_uint *)(data + SZ_INT + i);
-      PRAGMA_POP()
       reg += VAL2 - SZ_INT;
       DISPATCH()
     }
@@ -1287,8 +1265,321 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       VM_OUT
       vm_shred_exit(shred);
     } while (s->curr);
-//    MUTEX_UNLOCK(s->mutex);
   }
+    PRAGMA_POP()
+} else {
+//exit(3);
+//return;
+static void *_dispatch[] = {
+      &&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr,
+      &&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr,
+      &&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother,
+      &&_baseaddr, &&_regtoreg, &&_regtoregother, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef,
+      &&_structmember, &&_structmemberfloat, &&_structmemberother,
+      &&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat,
+      &&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint,
+      &&_allocfloat, &&_allocother,
+      &&_intplus, &&_intminus, &&_intmul, &&_intdiv, &&_intmod,
+      &&_intplusimm, &&_intminusimm, &&_intmulimm, &&_intdivimm, &&_intmodimm,
+      // int relationnal
+      &&_inteq, &&_intne, &&_intand, &&_intor,
+      &&_intgt, &&_intge, &&_intlt, &&_intle,
+      &&_intgtimm, &&_intgeimm, &&_intltimm, &&_intleimm,
+      &&_intsl, &&_intsr, &&_intsand, &&_intsor, &&_intxor, &&_intnegate, &&_intnot,
+      &&_intcmp, &&_intrassign, &&_intradd, &&_intrsub, &&_intrmul, &&_intrdiv,
+      &&_intrmod, &&_intrsl, &&_intrsr, &&_intrsand, &&_intrsor, &&_intrxor, &&_preinc,
+      &&_predec, &&_postinc, &&_postdec,
+      &&_floatadd, &&_floatsub, &&_floatmul, &&_floatdiv,
+      &&_floataddimm, &&_floatsubimm, &&_floatmulimm, &&_floatdivimm,
+      // logical
+      &&_floatand, &&_floator, &&_floateq, &&_floatne,
+      &&_floatgt, &&_floatge, &&_floatlt, &&_floatle,
+      &&_floatgtimm, &&_floatgeimm, &&_floatltimm, &&_floatleimm,
+      &&_floatneg, &&_floatnot, &&_floatrassign, &&_floatradd,
+      &&_floatrsub, &&_floatrmul, &&_floatrdiv, &&_ifadd, &&_ifsub, &&_ifmul, &&_ifdiv,
+      &&_ifand, &&_ifor, &&_ifeq, &&_ifne, &&_ifgt, &&_ifge, &&_iflt, &&_ifle,
+      &&_ifrassign, &&_ifradd, &&_ifrsub, &&_ifrmul, &&_ifrdiv, &&_fiadd, &&_fisub,
+      &&_fimul, &&_fidiv, &&_fiand, &&_fior, &&_fieq, &&_fine, &&_figt, &&_fige, &&_filt,
+      &&_file, &&_firassign, &&_firadd, &&_firsub, &&_firmul, &&_firdiv, &&_itof,
+      &&_ftoi, &&_timeadv, &&_recurs, &&_setcode, &&_regmove,
+      &&_regtomem, &&_regtomemother,
+      &&_overflow,
+      &&_funcusrend, &&_funcusrend2, &&_funcmemberend,
+      &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp,
+      &&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat,
+      &&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop,
+      &&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref,
+      &&_addrefaddr, &&_structaddref, &&_structaddrefaddr, &&_objassign, &&_assign,
+      &&_remref, &&_remref2, &&_except, &&_allocmemberaddr, &&_dotmember, &&_dotfloat,
+      &&_dotother, &&_dotaddr, &&_unioncheck, &&_unionint, &&_unionfloat,
+      &&_unionother, &&_unionaddr, &&_staticint, &&_staticfloat, &&_staticother,
+      &&_upvalueint, &&_upvaluefloat, &&_upvalueother, &&_upvalueaddr, &&_dotfunc,
+      &&_gacktype, &&_gackend, &&_gack, &&_try_ini,
+      &&_try_end, &&_handleeffect, &&_performeffect, &&_noop, &&_debugline,
+      &&_debugvalue, &&_debugpush, &&_debugpop, &&_eoc, &&_unroll2, &&_other,
+      &&_regpushimm};
+
+#define PREPARE(a) \
+_##a: \
+ *(void**)prepare_code = &&a;\
+prepare_code += BYTECODE_SZ;\
+goto *_dispatch[*(m_bit*)prepare_code];
+
+goto *_dispatch[*(m_bit*)prepare_code];
+    PREPARE(regsetimm);
+    PREPARE(regpushimm);
+    PREPARE(regpushfloat);
+    PREPARE(regpushother);
+    PREPARE(regpushaddr);
+    PREPARE(regpushmem);
+    PREPARE(regpushmemfloat);
+    PREPARE(regpushmemother);
+    PREPARE(regpushmemaddr);
+    PREPARE(regpushmemderef);
+    PREPARE(pushnow);
+    PREPARE(baseint);
+    PREPARE(basefloat);
+    PREPARE(baseother);
+    PREPARE(baseaddr);
+    PREPARE(regtoreg);
+    PREPARE(regtoregother);
+    PREPARE(regtoregother2);
+    PREPARE(regtoregaddr);
+    PREPARE(regtoregderef);
+    PREPARE(structmember);
+    PREPARE(structmemberfloat);
+    PREPARE(structmemberother);
+    PREPARE(structmemberaddr)
+    PREPARE(memsetimm);
+    PREPARE(memaddimm);
+    PREPARE(repeatidx);
+    PREPARE(repeat);
+    PREPARE(regpushme);
+    PREPARE(regpushmaybe);
+//    PREPARE(funcreturn);
+_funcreturn:
+ *(void**)prepare_code = &&funcreturn;
+return;
+
+    PREPARE(_goto);
+    PREPARE(allocint);
+    PREPARE(allocfloat);
+    PREPARE(allocother)
+    PREPARE(intplus);
+    PREPARE(intminus);
+    PREPARE(intmul);
+    PREPARE(intdiv);
+    PREPARE(intmod);
+    PREPARE(intplusimm);
+    PREPARE(intminusimm);
+    PREPARE(intmulimm);
+    PREPARE(intdivimm);
+    PREPARE(intmodimm);
+
+    PREPARE(inteq);
+    PREPARE(intne);
+    PREPARE(intand);
+    PREPARE(intor);
+    PREPARE(intgt);
+    PREPARE(intge);
+    PREPARE(intlt);
+    PREPARE(intle);
+    PREPARE(intgtimm);
+    PREPARE(intgeimm);
+    PREPARE(intltimm);
+    PREPARE(intleimm);
+    PREPARE(intsl);
+    PREPARE(intsr);
+    PREPARE(intsand);
+    PREPARE(intsor);
+    PREPARE(intxor);
+
+    PREPARE(intnegate);
+    PREPARE(intnot);
+    PREPARE(intcmp);
+
+    PREPARE(intrassign);
+
+    PREPARE(intradd);
+    PREPARE(intrsub);
+    PREPARE(intrmul);
+    PREPARE(intrdiv);
+    PREPARE(intrmod);
+    PREPARE(intrsl);
+    PREPARE(intrsr);
+    PREPARE(intrsand);
+    PREPARE(intrsor);
+    PREPARE(intrxor)
+
+    PREPARE(preinc);
+    PREPARE(predec);
+    PREPARE(postinc);
+    PREPARE(postdec);
+
+    PREPARE(floatadd);
+    PREPARE(floatsub);
+    PREPARE(floatmul);
+    PREPARE(floatdiv);
+    PREPARE(floataddimm);
+    PREPARE(floatsubimm);
+    PREPARE(floatmulimm);
+    PREPARE(floatdivimm);
+
+    PREPARE(floatand);
+    PREPARE(floator);
+    PREPARE(floateq);
+    PREPARE(floatne);
+    PREPARE(floatgt);
+    PREPARE(floatge);
+    PREPARE(floatlt);
+    PREPARE(floatle);
+    PREPARE(floatgtimm);
+    PREPARE(floatgeimm);
+    PREPARE(floatltimm);
+    PREPARE(floatleimm);
+
+    PREPARE(floatneg);
+    PREPARE(floatnot);
+
+    PREPARE(floatrassign);
+
+    PREPARE(floatradd);
+    PREPARE(floatrsub);
+    PREPARE(floatrmul);
+    PREPARE(floatrdiv);
+
+    PREPARE(ifadd);
+    PREPARE(ifsub);
+    PREPARE(ifmul);
+    PREPARE(ifdiv);
+
+    PREPARE(ifand);
+    PREPARE(ifor);
+    PREPARE(ifeq);
+    PREPARE(ifne);
+    PREPARE(ifgt);
+    PREPARE(ifge);
+    PREPARE(iflt);
+    PREPARE(ifle);
+
+    PREPARE(ifrassign);
+    PREPARE(ifradd);
+    PREPARE(ifrsub);
+    PREPARE(ifrmul);
+    PREPARE(ifrdiv);
+
+    PREPARE(fiadd);
+    PREPARE(fisub);
+    PREPARE(fimul);
+    PREPARE(fidiv);
+
+    PREPARE(fiand);
+    PREPARE(fior);
+    PREPARE(fieq);
+    PREPARE(fine);
+    PREPARE(figt);
+    PREPARE(fige);
+    PREPARE(filt);
+    PREPARE(file);
+
+    PREPARE(firassign);
+
+    PREPARE(firadd);
+    PREPARE(firsub);
+    PREPARE(firmul);
+    PREPARE(firdiv);
+
+    PREPARE(itof);
+    PREPARE(ftoi);
+
+    PREPARE(timeadv);
+
+    PREPARE(recurs);
+
+    PREPARE(setcode);
+    PREPARE(regmove);
+    PREPARE(regtomem);
+    PREPARE(regtomemother);
+    PREPARE(overflow);
+    PREPARE(funcusrend);
+    PREPARE(funcusrend2);
+    PREPARE(funcmemberend);
+    PREPARE(sporkini);
+    PREPARE(forkini);
+    PREPARE(sporkfunc);
+    PREPARE(sporkmemberfptr);
+    PREPARE(sporkexp);
+    PREPARE(sporkend);
+    PREPARE(brancheqint);
+    PREPARE(branchneint);
+    PREPARE(brancheqfloat);
+    PREPARE(branchnefloat);
+    PREPARE(unroll);
+    PREPARE(arrayappend);
+    PREPARE(autounrollinit);
+    PREPARE(autoloop);
+    PREPARE(arraytop);
+    PREPARE(arrayaccess);
+    PREPARE(arrayget);
+    PREPARE(arrayaddr);
+    PREPARE(newobj);
+    PREPARE(addref);
+    PREPARE(addrefaddr);
+    PREPARE(structaddref);
+    PREPARE(structaddrefaddr);
+    PREPARE(objassign);
+    PREPARE(assign);
+    PREPARE(remref);
+    PREPARE(remref2);
+    PREPARE(except);
+    PREPARE(allocmemberaddr);
+    PREPARE(dotmember);
+    PREPARE(dotfloat);
+    PREPARE(dotother);
+    PREPARE(dotaddr);
+    PREPARE(unioncheck);
+    PREPARE(unionint);
+    PREPARE(unionfloat);
+    PREPARE(unionother);
+    PREPARE(unionaddr);
+    PREPARE(staticint);
+    PREPARE(staticfloat);
+    PREPARE(staticother);
+    PREPARE(upvalueint);
+    PREPARE(upvaluefloat);
+    PREPARE(upvalueother);
+    PREPARE(upvalueaddr);
+    PREPARE(dotfunc);
+    PREPARE(gacktype);
+    PREPARE(gackend);
+    PREPARE(gack);
+    PREPARE(try_ini);
+    PREPARE(try_end);
+    PREPARE(handleeffect);
+    PREPARE(performeffect);
+    PREPARE(noop);
+_other:
+{
+  *(void**)prepare_code = &&other;
+  const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2);
+  if(exec == DTOR_EOC)return;
+  const Instr instr = *(Instr*)(prepare_code + SZ_INT);
+  if(exec == fast_except)
+    instr->opcode = (m_uint)&&noop;
+  else if(exec == SetFunc)
+    instr->opcode = (m_uint)&&regpushimm;
+  prepare_code += BYTECODE_SZ;\
+  goto *_dispatch[*(m_bit*)prepare_code];
+}
+    PREPARE(unroll2);
+    PREPARE(debugline);
+    PREPARE(debugvalue);
+    PREPARE(debugpush);
+    PREPARE(debugpop);
+_eoc:
+ *(void**)prepare_code = &&eoc;
+return;
+}
 }
 
 // remove me
index 1f8906b64f147f3cfe2f3fda04bedd7c6916ed9b..ae8a41ed477dffc537c4fd976cca8401b062cbd9 100644 (file)
@@ -53,7 +53,7 @@ static inline uint isgoto(const unsigned opcode) {
 }
 
 ANN static inline void setpc(const m_bit *data, const m_uint i) {
-  *(unsigned *)(data + 1) = i + 1;
+  *(m_uint *)(data + SZ_INT*3) = i + 1;
 }
 
 ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
@@ -78,7 +78,11 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
           next->opcode = eNoOp;
         }
         if ((instr->m_val = move)) {
+// *(m_uint*)data = instr->opcode;
+//          memcpy(data, instr, SZ_INT);
+//          memcpy(data + SZ_INT*2, instr + SZ_INT, SZ_INT*2);
           memcpy(data, instr, BYTECODE_SZ);
+
           setpc(data, i);
         } else {
           vector_add(&nop, i);
@@ -108,9 +112,9 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
       if (instr->opcode == eGoto && instr->m_val == i + 1) {
         instr->opcode = eNoOp;
         vector_add(&nop, i);
-      } else if (instr->opcode != eNoOp)
+      } else if (instr->opcode != eNoOp) {
         memcpy(data, instr, BYTECODE_SZ);
-      else
+      else
         vector_add(&nop, i);
     } else {
       *(m_bit *)(data)                = instr->opcode;
@@ -121,6 +125,7 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
   }
   if (!vector_size(&nop)) {
     vector_release(&nop);
+    vm_prepare(NULL, ptr);
     return ptr;
   }
   m_bit *const final =
@@ -154,6 +159,7 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
   }
   vector_release(&nop);
   mp_free2(p, sz * BYTECODE_SZ, ptr);
+    vm_prepare(NULL, final);
   return final;
 }
 
diff --git a/util b/util
index 7b668adba0cd3d9e6af45e9c30456b5a6f171d74..9b1b16a7f3c8583afaa7d68e1395fc70315e4f0f 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 7b668adba0cd3d9e6af45e9c30456b5a6f171d74
+Subproject commit 9b1b16a7f3c8583afaa7d68e1395fc70315e4f0f