]> Nishi Git Mirror - gwion.git/commitdiff
:art: debug instruction
authorJérémie Astor <fennecdjay@gmail.com>
Thu, 6 May 2021 21:26:48 +0000 (23:26 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Thu, 6 May 2021 21:29:05 +0000 (23:29 +0200)
16 files changed:
include/emit.h
include/gwi.h
include/gwion.h
include/opcode.h
include/vm.h
libcmdapp
opcode.txt
src/arg.c
src/emit/emit.c
src/gwion.c
src/lib/array.c
src/lib/modules.c
src/lib/shred.c
src/vm/vm.c
src/vm/vm_code.c
src/vm/vm_shred.c

index a9afcd1adf047a5f6f80c46d38bb509d95328e24..bd6b762cc1d0e3013e73f676a40cc9b62e9541bd 100644 (file)
@@ -26,6 +26,8 @@ struct EmitterInfo_ {
   VM_Code code;
   uint memoize;
   uint unroll;
+  uint line;
+  bool debug;
 };
 
 struct Emitter_ {
index 3f7add095330c37cfbec3f875828f3f76ab7bc0b..ac9c290510652c37798feb573a0f23d064ac1f32 100644 (file)
@@ -2,7 +2,7 @@
 #define __GWI
 
 #ifdef GWION_DOC
-#include "lint.h"
+#include "gwfmt.h"
 #define gwiheader(a,...) do { lint_nl(a->lint); lint_indent(a->lint); lint(a->lint, "{-}#!+ {/}%s{0}\n", __VA_ARGS__); } while(0)
 #define gwidoc(a,...)    do { lint_nl(a->lint); lint_indent(a->lint); lint(a->lint, "{-}#!- {/}%s{0}\n", __VA_ARGS__); } while(0)
 #define gwinote(a,...)   do { lint_indent(a->lint); lint(a->lint, "{-}#!- {/}%s{0}\n", __VA_ARGS__); } while(0)
index 5061063621551459572a9012b4100c3ff0396c52..89834da5b727b65f9dab77537b832ddf8a5ef65c 100644 (file)
@@ -35,4 +35,6 @@ ANN static inline Type type_class(const Gwion gwion, const Type t) {
   const Value v = nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name));
   return v->type;
 }
+
+ANN void gwion_set_debug(const Gwion gwion, const bool dbg);
 #endif
index fab83001aa37c4acfc957a7cede4a9bfeef9815d..d0e695d1ecfb340247d9d21f96c6b677ed3a49d7 100644 (file)
@@ -188,6 +188,10 @@ enum {
   eHandleEffect,
   ePerformEffect,
   eNoOp,
+  eDebugLine,
+  eDebugValue,
+  eDebugPush,
+  eDebugPop,
   eEOC,
   eUnroll2,
   eOP_MAX,
@@ -381,6 +385,10 @@ enum {
 #define  HandleEffect         (f_instr)eHandleEffect
 #define  PerformEffect        (f_instr)ePerformEffect
 #define  NoOp                 (f_instr)eNoOp
+#define  DebugLine            (f_instr)eDebugLine
+#define  DebugValue           (f_instr)eDebugValue
+#define  DebugPush            (f_instr)eDebugPush
+#define  DebugPop             (f_instr)eDebugPop
 #define  EOC                  (f_instr)eEOC
 #define  Unroll2              (f_instr)eUnroll2
 #define  OP_MAX               (f_instr)eOP_MAX
index 3e2944c555291e6e83aaf95fcf2d37a322569144..917cb0a1bd9c6ff8b543b14a9ce621bd3d18952e 100644 (file)
@@ -13,7 +13,7 @@ typedef struct VM_Code_* VM_Code;
 struct VM_Code_ {
   m_bit *bytecode;
   union {
-    Vector instr;
+    struct Vector_ instr;
     m_uint native_func;
   };
   size_t stack_depth;
@@ -35,6 +35,12 @@ typedef struct Shreduler_* Shreduler;
 typedef struct Emitter_   * Emitter;
 typedef struct VM_Shred_* VM_Shred;
 
+typedef struct Debugger_ {
+  struct Vector_ breakpoint;
+  Nspc nspc;
+  bool step;
+} Debugger;
+
 typedef struct VM_ {
   Shreduler shreduler;
   struct Vector_ ugen;
@@ -42,18 +48,18 @@ typedef struct VM_ {
   struct Gwion_* gwion;
   VM_Shred cleaner_shred;
   struct VM_ *parent;
+  Debugger debugger;
   uint32_t rand[2];
 } VM;
 
-
 struct ShredInfo_ {
   VM* vm;
   struct M_Object_* me;
-  m_str name;
   Vector args;
   MemPool mp;
   VM_Code orig;
   struct Vector_ frame;
+  struct Vector_ line;
 };
 
 struct ShredTick_ {
index 27eb025e264a6251f595c0177b51ee58987324f5..9a2bcfb85e5ca94cc6f2697f5a41c09c1c18db3f 160000 (submodule)
--- a/libcmdapp
+++ b/libcmdapp
@@ -1 +1 @@
-Subproject commit 27eb025e264a6251f595c0177b51ee58987324f5
+Subproject commit 9a2bcfb85e5ca94cc6f2697f5a41c09c1c18db3f
index bb4b88ecd39cf69eaf940142907f57a04628291f..73536e3af2323664fad5fee0c77a2902b93441d7 100644 (file)
@@ -185,6 +185,10 @@ TryEnd
 HandleEffect
 PerformEffect
 NoOp
+DebugLine
+DebugValue
+DebugPush
+DebugPop
 EOC
 Unroll2
 OP_MAX
index aa39573b74dc5d01b36cf9012c9111994dd574bb..15d51cb5e5423f96a86bc71acedbf03cf9b5fe33 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -18,6 +18,7 @@ enum {
   DRIVER, SRATE, NINPUT, NOUTPUT,
 // pp options
   DEFINE, UNDEF, INCLUDE,
+  DEBUG,
   NOPTIONS
 };
 
@@ -47,7 +48,8 @@ enum arg_type {
   ARG_STDIN,
   ARG_DEFINE,
   ARG_UNDEF,
-  ARG_INCLUDE
+  ARG_INCLUDE,
+  ARG_DEBUG
 };
 
 ANN static void arg_init(Arg* arg) {
@@ -68,6 +70,19 @@ ANN void arg_release(Arg* arg) {
   vector_release(&arg->config);
 }
 
+static inline bool _get_debug(const m_str dbg) {
+  if(!dbg || !strcmp(dbg, "true"))
+    return true;
+  if(!strcmp(dbg, "false"))
+    return false;
+  return atoi(dbg) ? true : false;
+}
+
+ANN static inline void get_debug(const Gwion gwion, const m_str dbg) {
+  const bool is_dbg = _get_debug(dbg);
+  gwion_set_debug(gwion, is_dbg);
+}
+
 ANN void arg_compile(const Gwion gwion, Arg *arg) {
   const Vector v = &arg->add;
   for(m_uint i = 0; i < vector_size(v); i++) {
@@ -87,6 +102,9 @@ ANN void arg_compile(const Gwion gwion, Arg *arg) {
       case ARG_INCLUDE:
         pparg_inc(gwion->ppa, (m_str)VPTR(v, ++i));
         break;
+      case ARG_DEBUG:
+        get_debug(gwion, (m_str)VPTR(v, ++i));
+        break;
     }
   }
 }
@@ -180,6 +198,11 @@ static void setup_options(cmdapp_t* app, cmdopt_t* opt) {
         CMDOPT_TAKESARG, NULL,
         "add ARG to include path", &opt[INCLUDE]
     );
+    cmdapp_set(app,
+        'G', "debug",
+        CMDOPT_MAYTAKEARG, NULL,
+        "set/unset debug mode", &opt[DEBUG]
+    );
 }
 
 static inline void add2arg(Arg *const arg, const char *data, const enum arg_type type) {
@@ -299,6 +322,10 @@ static void myproc(void *data, cmdopt_t* option, const char* arg) {
         case 'I':
           add2arg(_arg, option->value, ARG_INCLUDE);
           break;
+// debug
+        case 'G':
+          add2arg(_arg, option->value, ARG_DEBUG);
+          break;
     }
   }
 }
index 6255ac28a9a51e2b2a94a5521af4878720fcfdd6..9791df9a70dfd49dc035c624921866171eb9e1d1 100644 (file)
@@ -41,6 +41,13 @@ static inline m_uint emit_push_global(const Emitter emit) {
   return env_push_global(emit->env);
 }
 
+static inline void emit_debug(const Emitter emit, const Value v) {
+  if(!emit->info->debug)
+    return;
+  const Instr instr = emit_add_instr(emit, DebugValue);
+  instr->m_val = (m_uint)v;
+}
+
 ANEW static Frame* new_frame(MemPool p) {
   Frame* frame = mp_calloc(p, Frame);
   vector_init(&frame->stack);
@@ -243,11 +250,15 @@ ANN static void emit_pop_scope(const Emitter emit) {
     instr->m_val = (m_uint)offset;
   }
   vector_pop(&emit->info->pure);
+  if(emit->info->debug)
+    emit_add_instr(emit, DebugPop);
 }
 
 ANN static inline void emit_push_code(const Emitter emit, const m_str name) {
   vector_add(&emit->stack, (vtype)emit->code);
   emit->code = new_code(emit, name);
+  if(emit->info->debug)
+    emit_add_instr(emit, DebugLine);
 }
 
 ANN static inline void emit_pop_code(const Emitter emit) {
@@ -257,6 +268,8 @@ ANN static inline void emit_pop_code(const Emitter emit) {
 ANN static inline void emit_push_scope(const Emitter emit) {
   frame_push(emit->code->frame);
   vector_add(&emit->info->pure, 0);
+  if(emit->info->debug)
+    emit_add_instr(emit, DebugPush);
 }
 
 ANN static inline m_uint emit_code_size(const Emitter emit) {
@@ -805,6 +818,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
   f_instr *exec = (f_instr*)allocmember;
   if(!vflag(v, vflag_member)) {
     v->from->offset = emit_local(emit, type);
+    emit_debug(emit, v);
     exec = (f_instr*)(allocword);
     if(GET_FLAG(v, late)) { // ref or emit_var ?
       const Instr clean = emit_add_instr(emit, MemSetImm);
@@ -1501,10 +1515,13 @@ ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) {
 
 DECL_EXP_FUNC(emit, m_bool, Emitter)
 
-
 ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) {
   Exp exp = e;
   do {
+    if(emit->info->debug && emit->info->line < e->pos.first.line) {
+      const Instr instr = emit_add_instr(emit, DebugLine);
+      instr->m_val = emit->info->line = e->pos.first.line;
+    }
     CHECK_BB(emit_exp_func[exp->exp_type](emit, &exp->d));
     if(exp->cast_to)
       CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to));
@@ -1546,8 +1563,10 @@ ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
 }
 
 ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) {
+  emit_push_scope(emit);
   ++emit->env->scope->depth;
   const m_bool ret = stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1;
+  emit_pop_scope(emit);
   --emit->env->scope->depth;
   return ret;
 }
@@ -1810,6 +1829,7 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_ui
   loop_idx->m_val = offset + SZ_INT;
   loop_idx->m_val2 = -1;
   stmt->v->from->offset = offset + SZ_INT *2;
+  emit_debug(emit, stmt->v);
   if(stmt->idx)
     stmt->idx->v->from->offset = offset + SZ_INT;
   if(n) {
@@ -1984,6 +2004,7 @@ ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* s
 ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
   const Value v = e->d.prim.value;
   v->from->offset = emit_local(emit, base->type);
+  emit_debug(emit, v);
   const Instr instr = emit_add_instr(emit, Reg2Mem4);
   instr->m_val = v->from->offset;
   instr->m_val2 = base->type->size;
@@ -2173,6 +2194,7 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List a) {
     const Type type = a->var_decl->value->type;
     emit->code->stack_depth += type->size;
     a->var_decl->value->from->offset = emit_localn(emit, type);
+    emit_debug(emit, a->var_decl->value);
   } while((a = a->next));
 }
 
index 361f96d2282be2039a0cd5378cb2ba14db1dde5d..879843a5955c1948b2bb1e1ab74cba725c487aab 100644 (file)
@@ -207,3 +207,7 @@ ANN Nspc pop_global(struct Gwion_ *gwion) {
   nspc_remref(gwion->env->global_nspc, gwion);
   return gwion->env->curr = gwion->env->global_nspc = nspc;
 }
+
+ANN void gwion_set_debug(const Gwion gwion, const bool dbg) {
+  gwion->emit->info->debug = dbg;
+}
index 5c0077dc3012fef27290d0d08a828d060cd4eca2..ba652879253360820bc4f9506ae1206d33f09ecd 100644 (file)
@@ -922,7 +922,7 @@ INSTR(ArrayAlloc) {
     aai.data = init_array(shred, info, &num_obj);
   const M_Object ref = do_alloc_array(shred, &aai);
   if(!ref) {
-    gw_err("[Gwion](VM): (note: in shred[id=%" UINT_F ":%s])\n", shred->tick->xid, shred->info->name);
+    gw_err("[Gwion](VM): (note: in shred[id=%" UINT_F ":%s])\n", shred->tick->xid, shred->code->name);
     vm_shred_exit(shred);
     return; // TODO make exception vararg
   }
index c1c22207b1a2aa320f54bfefe4ba83244aebe835..016d6e638d597e8cbef62096e020bad4c8d67128 100644 (file)
@@ -226,7 +226,7 @@ static INSTR(UURet) {
 
 ANN static void code_prepare(const VM_Code code) {
   m_bit *byte = code->bytecode;
-  for(m_uint i = 0; i < vector_size(code->instr); ++i) {
+  for(m_uint i = 0; i < vector_size(&code->instr); ++i) {
     if(*(m_bit*)(byte + i *BYTECODE_SZ) == eFuncReturn) {
       *(m_bit*)(byte + i * BYTECODE_SZ)= eOP_MAX;
       *(f_instr*)(byte + (i*BYTECODE_SZ) + SZ_INT*2) = UURet;
index ebf21334074103e90c7d99482e09f19efd173f03..756d6e70348801935ecae71ba61a015e2111f4f7 100644 (file)
@@ -124,7 +124,7 @@ static MFUN(shred##name##_name) { \
   const m_str str = code_name((src), 0); \
   *(m_uint*)RETURN = (m_uint)new_string(shred->info->mp, shred, str); \
 }
-describe_name(, s->info->name)
+describe_name(, s->info->orig->name)
 describe_name(_code, s->code->name)
 
 #define describe_path_and_dir(name, src) \
@@ -149,7 +149,7 @@ static MFUN(shred##name##_dir) { \
   }\
   *(m_uint*)RETURN = (m_uint)new_string(shred->info->mp, shred, c); \
 }
-describe_path_and_dir(, s->info->name)
+describe_path_and_dir(, s->info->orig->name)
 describe_path_and_dir(_code, s->code->name)
 
 static DTOR(shred_dtor) {
index 5692ccd11317cfa371feda191abf65f926e01c48..3bd9f36383cc087bdbc66dec631a1186bcdb9589 100644 (file)
@@ -40,11 +40,17 @@ uint32_t gw_rand(uint32_t s[2]) {
   return ret;
 }
 
-ANN static bool unwind(VM_Shred shred, const Symbol effect) {
-  if(!shred->info->frame.ptr || !vector_size(&shred->info->frame))
+ANN static inline void shred_unwind(VM_Shred shred) {
+  shred->pc   = *(m_uint*) (shred->mem - SZ_INT * 2);
+  shred->code = *(VM_Code*)(shred->mem - SZ_INT * 3);
+  shred->mem -= (*(m_uint*)(shred->mem - SZ_INT * 4) + SZ_INT * 4);
+}
+
+ANN static bool unwind(VM_Shred shred, const Symbol effect, const m_uint size) {
+  if(!size)
     return true;
   if(shred->code->handlers.ptr) {
-    const m_uint start = VKEY(&shred->info->frame, VLEN(&shred->info->frame) - 1);
+    const m_uint start = VKEY(&shred->info->frame, size - 1);
     if(start > shred->pc)
       return true;
     const Map m = &shred->code->handlers;
@@ -54,7 +60,7 @@ ANN static bool unwind(VM_Shred shred, const Symbol effect) {
         break;
       if(start < shred->pc && VKEY(m, i) > shred->pc) {
          const m_uint next = VKEY(m, i);
-         const Instr instr = (Instr)vector_at(shred->code->instr, next + 1);
+         const Instr instr = (Instr)vector_at(&shred->code->instr, next + 1);
          if(!instr->m_val2 || (Symbol)instr->m_val2 == effect) {
            pc = next + 1;
            break;
@@ -66,31 +72,50 @@ ANN static bool unwind(VM_Shred shred, const Symbol effect) {
     shred->reg = (m_bit*)VPTR(&shred->info->frame, VLEN(&shred->info->frame) - 1);
     shredule(shred->tick->shreduler, shred, 0);
     shred->pc = pc;//VKEY(m, i);
+    // should we pop?
+    VLEN(&shred->info->frame) = size;
     return false;
   }
   // there might be no more stack to unwind
-  vector_pop(&shred->info->frame);
-  vector_pop(&shred->info->frame);
   if(shred->mem == (m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG)
     return true;
-  // literally unwind
-  shred->pc   = *(m_uint*) (shred->mem - SZ_INT * 2);
-  shred->code = *(VM_Code*)(shred->mem - SZ_INT * 3);
-  shred->mem -= (*(m_uint*)(shred->mem - SZ_INT * 4) + SZ_INT * 4);
-  return unwind(shred, effect);
+  shred_unwind(shred);
+  return unwind(shred, effect, size - 2);
+}
+
+ANN static void trace(VM_Shred shred, const m_uint size) {
+  const m_uint line = vector_at(&shred->info->line, size-1);
+  m_uint i;
+  for(i = size; --i;) {
+    if(VPTR(&shred->info->line, i-1))
+      break;
+  }
+  loc_t loc = {.first={.line=line, .column=1},.last={.line=line, .column=1}};
+  gw_err("      {-B}┃{0} in function {+}%s{0}{-}:{0}\n", shred->code->name);
+  gwerr_secondary("called from here", code_name(shred->code->name, true), loc);
+  if(shred->mem == (m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG)
+    return;
+  shred_unwind(shred);
+  trace(shred, i);
 }
 
 ANN void handle(VM_Shred shred, const m_str effect) {
-  // remove from the shreduler
-  // TODO: get shred->mem and shred->reg offsets
+  m_bit *const reg = shred->reg;
+  m_bit *const mem = shred->mem;
+  const m_uint size = shred->info->frame.ptr ?
+    vector_size(&shred->info->frame) : 0;
+  const VM_Code code = shred->code;
   shreduler_remove(shred->tick->shreduler, shred, false);
-  // do the unwiding
-  if(unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect))) {
-    vm_shred_exit(shred);
-    gw_err("{-C}shred{W}[{Y}% 5" UINT_F "{W}]{-}: {-R}Unhandled {+R}%s{0}\n", shred->tick->xid, effect);
+  if(!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size))
+    return;
+  gw_err("{-C}shred{W}[{Y}% 5" UINT_F "{W}]{-}: {-R}Unhandled {+R}%s{0}\n", shred->tick->xid, effect);
+  if(shred->info->line.ptr) { // trace if available
+    shred->reg = reg;
+    shred->mem = mem;
+    shred->code = code;
+    trace(shred, vector_size(&shred->info->line));
   }
-  // I guess the VM could have *trace mode*
-  // which would happen here from the top
+  vm_shred_exit(shred);
 }
 
 
@@ -385,7 +410,9 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
     &&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr,
     &&dotfunc,
     &&gcini, &&gcadd, &&gcend,
-    &&gacktype, &&gackend, &&gack, &&try_ini, &&try_end, &&handleeffect, &&performeffect, &&noop, &&eoc, &&unroll2, &&other, &&regpushimm
+    &&gacktype, &&gackend, &&gack, &&try_ini, &&try_end, &&handleeffect, &&performeffect, &&noop,
+    &&debugline, &&debugvalue, &&debugpush, &&debugpop,
+    &&eoc, &&unroll2, &&other, &&regpushimm
   };
   const Shreduler s = vm->shreduler;
   register VM_Shred shred;
@@ -1019,9 +1046,9 @@ handleeffect:
 // this should check the *xid* of the exception
   DISPATCH();
 performeffect:
+  VM_OUT
   handle(shred, (m_str)VAL);
   break;
-// this should check the *xid* of the exception
 noop:
   DISPATCH();
 other:
@@ -1035,6 +1062,27 @@ in:
   reg = shred->reg;
   mem = shred->mem;
   PC_DISPATCH(shred->pc)
+debugline:
+  if(!shred->info->line.ptr) {// from a problem with spork it seems
+    vector_init(&shred->info->line);
+    vector_add(&shred->info->line, VAL);
+  } else if(!VAL) {
+    vector_add(&shred->info->line, VAL);
+  } else {
+    const m_uint sz = vector_size(&shred->info->line);
+    vector_set(&shred->info->line, sz - 1, VAL);
+  }
+  DISPATCH();
+debugvalue:
+  DISPATCH();
+debugpush:
+  if(!shred->info->line.ptr)
+    vector_init(&shred->info->line);
+  vector_add(&shred->info->line, 0);
+  DISPATCH();
+debugpop:
+  vector_pop(&shred->info->line);
+  DISPATCH();
 eoc:
   VM_OUT
   vm_shred_exit(shred);
index aed65b8a4bd49cf33c78f40c75a2ebd1d4854a9f..1aa3ae8927d259be20d1207c07a4b4163c2a3fa1 100644 (file)
@@ -23,7 +23,7 @@ ANN void free_code_instr(const Vector v, const Gwion gwion) {
 
 ANN void free_vmcode(VM_Code a, Gwion gwion) {
   if(!a->builtin) {
-    _mp_free(gwion->mp, vector_size(a->instr) * BYTECODE_SZ, a->bytecode);
+    _mp_free(gwion->mp, vector_size(&a->instr) * BYTECODE_SZ, a->bytecode);
     if(likely(!a->callback)) {
       if(a->closure) {
         if(!a->is_memoize)
@@ -31,11 +31,11 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) {
         else
           memoize_end(gwion->mp, a->memoize);
       }
-      free_code_instr(a->instr, gwion);
+      free_code_instr(&a->instr, gwion);
     }
     if(a->handlers.ptr)
       map_release(&a->handlers);
-    free_vector(gwion->mp, a->instr);
+    vector_release(&a->instr);
   }
   free_mstr(gwion->mp, a->name);
   mp_free(gwion->mp , VM_Code, a);
@@ -53,7 +53,7 @@ static inline void setpc(const m_bit *data, const m_uint i) {
 }
 
 ANN static m_bit* tobytecode(MemPool p, const VM_Code code) {
-   const Vector v = code->instr;
+  const Vector v = &code->instr;
   const m_uint sz = vector_size(v);
   m_bit *ptr = _mp_malloc(p, sz * BYTECODE_SZ);
   struct Vector_ nop;
@@ -155,7 +155,9 @@ VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth,
   VM_Code code           = mp_calloc(p, VM_Code);
   code->name             = mstrdup(p, name);
   if(instr) {
-    code->instr            = vector_copy(p, instr);
+//    code->instr            = vector_copy(p, instr);
+    vector_init(&code->instr);
+    vector_copy2(instr, &code->instr);
     code->bytecode = tobytecode(p, code);
   }
   code->stack_depth      = stack_depth;
@@ -169,9 +171,9 @@ VM_Code new_vmcode(MemPool p, const Vector instr, const m_uint stack_depth,
 VM_Code vmcode_callback(MemPool mp, VM_Code base) {
   char name[strlen(base->name) + 11];
   sprintf(name, "%s(callback)", base->name);
-  const Instr instr = (Instr)vector_back(base->instr);
+  const Instr instr = (Instr)vector_back(&base->instr);
   instr->opcode = eEOC;
-  VM_Code code = new_vmcode(mp, base->instr, base->stack_depth, base->builtin, name);
+  VM_Code code = new_vmcode(mp, &base->instr, base->stack_depth, base->builtin, name);
   code->closure = base->closure;
   code->callback = 1;
   instr->opcode = eFuncReturn;
index 737f8b783902f3cb5687ac1fac16e050f6105eff..b81a4e5498e8deaa501d3a906b8a76c738a3fe4c 100644 (file)
@@ -11,22 +11,23 @@ struct Stack_ {
   char d[SIZEOF_MEM];
 };
 
-static inline struct ShredInfo_ *new_shredinfo(MemPool p, const m_str name) {
+static inline struct ShredInfo_ *new_shredinfo(MemPool p, const VM_Code c) {
   struct ShredInfo_ *info = mp_calloc(p, ShredInfo);
   info->mp = p;
-  info->name = mstrdup(p, name);
+  info->orig = c;
   return info;
 }
 
 static inline void free_shredinfo(MemPool mp, struct ShredInfo_ *info) {
-  free_mstr(mp, info->name);
-  if(info->args) {
+  if(info->args) { // could be a struct
     const Vector v = info->args;
     LOOP_OPTIM
     for(m_uint i = vector_size(v) + 1; --i;)
       xfree((void*)vector_at(v, i - 1));
     free_vector(mp, v);
   }
+  if(info->line.ptr)
+    vector_release(&info->line);
   mp_free(mp, ShredInfo, info);
 }
 
@@ -35,8 +36,7 @@ VM_Shred new_vm_shred(MemPool p, VM_Code c) {
   shred->code = c;
   shred->reg  = (m_bit*)shred + sizeof(struct VM_Shred_);
   shred->base = shred->mem = shred->reg + SIZEOF_REG;
-  shred->info = new_shredinfo(p, c->name);
-  shred->info->orig = c;
+  shred->info = new_shredinfo(p, c);
   vector_init(&shred->gc);
   return shred;
 }