]> Nishi Git Mirror - gwion.git/commitdiff
:art: Allow code dump
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 27 Jun 2021 22:31:55 +0000 (00:31 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 27 Jun 2021 22:31:55 +0000 (00:31 +0200)
16 files changed:
include/emit.h
include/gwion.h
include/opcode.h
include/vm.h
opcode.txt
plug
scripts/opcode.sh
src/arg.c
src/emit/emitter.c
src/env/func.c
src/gwion.c
src/import/import_cdef.c
src/import/import_special.c
src/lib/array.c
src/lib/ptr.c
src/vm/vm_code.c

index 56837bcfcd017b59954fdd2ecd7d802eea2de53b..64063f8a1e17e6fa08cf61fb3d820b430bf98d45 100644 (file)
@@ -37,6 +37,7 @@ struct EmitterInfo_ {
   uint16_t unroll;
   uint16_t line;
   bool     debug;
+  bool     dump;
 };
 
 struct Emitter_ {
index 94fb00d6f6d9a885490b7bbdfc69fef0d3c4b211..041333b8e305b90e00cc4ad3b3338521959091e0 100644 (file)
@@ -39,5 +39,6 @@ type_class(const Gwion gwion, const Type t) {
 }
 
 ANN void gwion_set_debug(const Gwion gwion, const bool dbg);
+ANN void gwion_set_dump(const Gwion gwion, const bool dump);
 ANN void gwion_set_cdoc(const Gwion gwion, const bool dbg);
 #endif
index aaa6b6d1a348194ac1a32c6e3a45f249e8469736..e0ef81b65d7fb1aaca8f59f3bf693a3ef259e778 100644 (file)
@@ -202,203 +202,1125 @@ enum {
   eDotTmplVal,
 };
 
-#define RegSetImm           (f_instr) eRegSetImm
-#define RegPushImm          (f_instr) eRegPushImm
-#define RegPushImm2         (f_instr) eRegPushImm2
-#define RegPushImm3         (f_instr) eRegPushImm3
-#define RegPushImm4         (f_instr) eRegPushImm4
-#define RegPushMem          (f_instr) eRegPushMem
-#define RegPushMem2         (f_instr) eRegPushMem2
-#define RegPushMem3         (f_instr) eRegPushMem3
-#define RegPushMem4         (f_instr) eRegPushMem4
-#define RegPushMemDeref     (f_instr) eRegPushMemDeref
-#define RegPushNow          (f_instr) eRegPushNow
-#define RegPushBase         (f_instr) eRegPushBase
-#define RegPushBase2        (f_instr) eRegPushBase2
-#define RegPushBase3        (f_instr) eRegPushBase3
-#define RegPushBase4        (f_instr) eRegPushBase4
-#define Reg2Reg             (f_instr) eReg2Reg
-#define Reg2RegOther        (f_instr) eReg2RegOther
-#define Reg2RegAddr         (f_instr) eReg2RegAddr
-#define Reg2RegDeref        (f_instr) eReg2RegDeref
-#define StructMember        (f_instr) eStructMember
-#define StructMemberFloat   (f_instr) eStructMemberFloat
-#define StructMemberOther   (f_instr) eStructMemberOther
-#define StructMemberAddr    (f_instr) eStructMemberAddr
-#define MemSetImm           (f_instr) eMemSetImm
-#define MemAddImm           (f_instr) eMemAddImm
-#define RepeatIdx           (f_instr) eRepeatIdx
-#define Repeat              (f_instr) eRepeat
-#define RegPushMe           (f_instr) eRegPushMe
-#define RegPushMaybe        (f_instr) eRegPushMaybe
-#define FuncReturn          (f_instr) eFuncReturn
-#define Goto                (f_instr) eGoto
-#define AllocWord           (f_instr) eAllocWord
-#define AllocWord2          (f_instr) eAllocWord2
-#define AllocWord3          (f_instr) eAllocWord3
-#define int_plus            (f_instr) eint_plus
-#define int_minus           (f_instr) eint_minus
-#define int_mul             (f_instr) eint_mul
-#define int_div             (f_instr) eint_div
-#define int_modulo          (f_instr) eint_modulo
-#define int_eq              (f_instr) eint_eq
-#define int_neq             (f_instr) eint_neq
-#define int_and             (f_instr) eint_and
-#define int_or              (f_instr) eint_or
-#define int_gt              (f_instr) eint_gt
-#define int_ge              (f_instr) eint_ge
-#define int_lt              (f_instr) eint_lt
-#define int_le              (f_instr) eint_le
-#define int_sl              (f_instr) eint_sl
-#define int_sr              (f_instr) eint_sr
-#define int_sand            (f_instr) eint_sand
-#define int_sor             (f_instr) eint_sor
-#define int_xor             (f_instr) eint_xor
-#define int_negate          (f_instr) eint_negate
-#define IntNot              (f_instr) eIntNot
-#define int_cmp             (f_instr) eint_cmp
-#define int_r_assign        (f_instr) eint_r_assign
-#define int_r_plus          (f_instr) eint_r_plus
-#define int_r_minus         (f_instr) eint_r_minus
-#define int_r_mul           (f_instr) eint_r_mul
-#define int_r_div           (f_instr) eint_r_div
-#define int_r_modulo        (f_instr) eint_r_modulo
-#define int_r_sl            (f_instr) eint_r_sl
-#define int_r_sr            (f_instr) eint_r_sr
-#define int_r_sand          (f_instr) eint_r_sand
-#define int_r_sor           (f_instr) eint_r_sor
-#define int_r_sxor          (f_instr) eint_r_sxor
-#define int_pre_inc         (f_instr) eint_pre_inc
-#define int_pre_dec         (f_instr) eint_pre_dec
-#define int_post_inc        (f_instr) eint_post_inc
-#define int_post_dec        (f_instr) eint_post_dec
-#define FloatPlus           (f_instr) eFloatPlus
-#define FloatMinus          (f_instr) eFloatMinus
-#define FloatTimes          (f_instr) eFloatTimes
-#define FloatDivide         (f_instr) eFloatDivide
-#define float_and           (f_instr) efloat_and
-#define float_or            (f_instr) efloat_or
-#define float_eq            (f_instr) efloat_eq
-#define float_neq           (f_instr) efloat_neq
-#define float_gt            (f_instr) efloat_gt
-#define float_ge            (f_instr) efloat_ge
-#define float_lt            (f_instr) efloat_lt
-#define float_le            (f_instr) efloat_le
-#define float_negate        (f_instr) efloat_negate
-#define float_not           (f_instr) efloat_not
-#define float_r_assign      (f_instr) efloat_r_assign
-#define float_r_plus        (f_instr) efloat_r_plus
-#define float_r_minus       (f_instr) efloat_r_minus
-#define float_r_mul         (f_instr) efloat_r_mul
-#define float_r_div         (f_instr) efloat_r_div
-#define int_float_plus      (f_instr) eint_float_plus
-#define int_float_minus     (f_instr) eint_float_minus
-#define int_float_mul       (f_instr) eint_float_mul
-#define int_float_div       (f_instr) eint_float_div
-#define int_float_and       (f_instr) eint_float_and
-#define int_float_or        (f_instr) eint_float_or
-#define int_float_eq        (f_instr) eint_float_eq
-#define int_float_neq       (f_instr) eint_float_neq
-#define int_float_gt        (f_instr) eint_float_gt
-#define int_float_ge        (f_instr) eint_float_ge
-#define int_float_lt        (f_instr) eint_float_lt
-#define int_float_le        (f_instr) eint_float_le
-#define int_float_r_assign  (f_instr) eint_float_r_assign
-#define int_float_r_plus    (f_instr) eint_float_r_plus
-#define int_float_r_minus   (f_instr) eint_float_r_minus
-#define int_float_r_mul     (f_instr) eint_float_r_mul
-#define int_float_r_div     (f_instr) eint_float_r_div
-#define float_int_plus      (f_instr) efloat_int_plus
-#define float_int_minus     (f_instr) efloat_int_minus
-#define float_int_mul       (f_instr) efloat_int_mul
-#define float_int_div       (f_instr) efloat_int_div
-#define float_int_and       (f_instr) efloat_int_and
-#define float_int_or        (f_instr) efloat_int_or
-#define float_int_eq        (f_instr) efloat_int_eq
-#define float_int_neq       (f_instr) efloat_int_neq
-#define float_int_gt        (f_instr) efloat_int_gt
-#define float_int_ge        (f_instr) efloat_int_ge
-#define float_int_lt        (f_instr) efloat_int_lt
-#define float_int_le        (f_instr) efloat_int_le
-#define float_int_r_assign  (f_instr) efloat_int_r_assign
-#define float_int_r_plus    (f_instr) efloat_int_r_plus
-#define float_int_r_minus   (f_instr) efloat_int_r_minus
-#define float_int_r_mul     (f_instr) efloat_int_r_mul
-#define float_int_r_div     (f_instr) efloat_int_r_div
-#define CastI2F             (f_instr) eCastI2F
-#define CastF2I             (f_instr) eCastF2I
-#define Time_Advance        (f_instr) eTime_Advance
-#define Recurs              (f_instr) eRecurs
-#define SetCode             (f_instr) eSetCode
-#define RegMove             (f_instr) eRegMove
-#define Reg2Mem             (f_instr) eReg2Mem
-#define Reg2Mem4            (f_instr) eReg2Mem4
-#define Overflow            (f_instr) eOverflow
-#define FuncUsrEnd          (f_instr) eFuncUsrEnd
-#define FuncUsrEnd2         (f_instr) eFuncUsrEnd2
-#define FuncMemberEnd       (f_instr) eFuncMemberEnd
-#define SporkIni            (f_instr) eSporkIni
-#define ForkIni             (f_instr) eForkIni
-#define SporkFunc           (f_instr) eSporkFunc
-#define SporkMemberFptr     (f_instr) eSporkMemberFptr
-#define SporkExp            (f_instr) eSporkExp
-#define SporkEnd            (f_instr) eSporkEnd
-#define BranchEqInt         (f_instr) eBranchEqInt
-#define BranchNeqInt        (f_instr) eBranchNeqInt
-#define BranchEqFloat       (f_instr) eBranchEqFloat
-#define BranchNeqFloat      (f_instr) eBranchNeqFloat
-#define Unroll              (f_instr) eUnroll
-#define ArrayAppend         (f_instr) eArrayAppend
-#define AutoUnrollInit      (f_instr) eAutoUnrollInit
-#define AutoLoop            (f_instr) eAutoLoop
-#define ArrayTop            (f_instr) eArrayTop
-#define ArrayAccess         (f_instr) eArrayAccess
-#define ArrayGet            (f_instr) eArrayGet
-#define ArrayAddr           (f_instr) eArrayAddr
-#define ObjectInstantiate   (f_instr) eObjectInstantiate
-#define RegAddRef           (f_instr) eRegAddRef
-#define RegAddRefAddr       (f_instr) eRegAddRefAddr
-#define StructRegAddRef     (f_instr) eStructRegAddRef
-#define StructRegAddRefAddr (f_instr) eStructRegAddRefAddr
-#define ObjectAssign        (f_instr) eObjectAssign
-#define Assign              (f_instr) eAssign
-#define ObjectRelease       (f_instr) eObjectRelease
-#define GWOP_EXCEPT         (f_instr) eGWOP_EXCEPT
-#define AllocMember4        (f_instr) eAllocMember4
-#define DotMember           (f_instr) eDotMember
-#define DotMember2          (f_instr) eDotMember2
-#define DotMember3          (f_instr) eDotMember3
-#define DotMember4          (f_instr) eDotMember4
-#define UnionCheck          (f_instr) eUnionCheck
-#define UnionMember         (f_instr) eUnionMember
-#define UnionMember2        (f_instr) eUnionMember2
-#define UnionMember3        (f_instr) eUnionMember3
-#define UnionMember4        (f_instr) eUnionMember4
-#define DotStatic           (f_instr) eDotStatic
-#define DotStatic2          (f_instr) eDotStatic2
-#define DotStatic3          (f_instr) eDotStatic3
-#define UpvalueInt          (f_instr) eUpvalueInt
-#define UpvalueFloat        (f_instr) eUpvalueFloat
-#define UpvalueOther        (f_instr) eUpvalueOther
-#define UpvalueAddr         (f_instr) eUpvalueAddr
-#define DotFunc             (f_instr) eDotFunc
-#define GcIni               (f_instr) eGcIni
-#define GcAdd               (f_instr) eGcAdd
-#define GcEnd               (f_instr) eGcEnd
-#define GackType            (f_instr) eGackType
-#define GackEnd             (f_instr) eGackEnd
-#define Gack                (f_instr) eGack
-#define TryIni              (f_instr) eTryIni
-#define TryEnd              (f_instr) eTryEnd
-#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
-#define DotTmplVal          (f_instr) eDotTmplVal
+#define  RegSetImm            (f_instr)eRegSetImm
+#define  RegPushImm           (f_instr)eRegPushImm
+#define  RegPushImm2          (f_instr)eRegPushImm2
+#define  RegPushImm3          (f_instr)eRegPushImm3
+#define  RegPushImm4          (f_instr)eRegPushImm4
+#define  RegPushMem           (f_instr)eRegPushMem
+#define  RegPushMem2          (f_instr)eRegPushMem2
+#define  RegPushMem3          (f_instr)eRegPushMem3
+#define  RegPushMem4          (f_instr)eRegPushMem4
+#define  RegPushMemDeref      (f_instr)eRegPushMemDeref
+#define  RegPushNow           (f_instr)eRegPushNow
+#define  RegPushBase          (f_instr)eRegPushBase
+#define  RegPushBase2         (f_instr)eRegPushBase2
+#define  RegPushBase3         (f_instr)eRegPushBase3
+#define  RegPushBase4         (f_instr)eRegPushBase4
+#define  Reg2Reg              (f_instr)eReg2Reg
+#define  Reg2RegOther         (f_instr)eReg2RegOther
+#define  Reg2RegAddr          (f_instr)eReg2RegAddr
+#define  Reg2RegDeref         (f_instr)eReg2RegDeref
+#define  StructMember         (f_instr)eStructMember
+#define  StructMemberFloat    (f_instr)eStructMemberFloat
+#define  StructMemberOther    (f_instr)eStructMemberOther
+#define  StructMemberAddr     (f_instr)eStructMemberAddr
+#define  MemSetImm            (f_instr)eMemSetImm
+#define  MemAddImm            (f_instr)eMemAddImm
+#define  RepeatIdx            (f_instr)eRepeatIdx
+#define  Repeat               (f_instr)eRepeat
+#define  RegPushMe            (f_instr)eRegPushMe
+#define  RegPushMaybe         (f_instr)eRegPushMaybe
+#define  FuncReturn           (f_instr)eFuncReturn
+#define  Goto                 (f_instr)eGoto
+#define  AllocWord            (f_instr)eAllocWord
+#define  AllocWord2           (f_instr)eAllocWord2
+#define  AllocWord3           (f_instr)eAllocWord3
+#define  int_plus             (f_instr)eint_plus
+#define  int_minus            (f_instr)eint_minus
+#define  int_mul              (f_instr)eint_mul
+#define  int_div              (f_instr)eint_div
+#define  int_modulo           (f_instr)eint_modulo
+#define  int_eq               (f_instr)eint_eq
+#define  int_neq              (f_instr)eint_neq
+#define  int_and              (f_instr)eint_and
+#define  int_or               (f_instr)eint_or
+#define  int_gt               (f_instr)eint_gt
+#define  int_ge               (f_instr)eint_ge
+#define  int_lt               (f_instr)eint_lt
+#define  int_le               (f_instr)eint_le
+#define  int_sl               (f_instr)eint_sl
+#define  int_sr               (f_instr)eint_sr
+#define  int_sand             (f_instr)eint_sand
+#define  int_sor              (f_instr)eint_sor
+#define  int_xor              (f_instr)eint_xor
+#define  int_negate           (f_instr)eint_negate
+#define  IntNot               (f_instr)eIntNot
+#define  int_cmp              (f_instr)eint_cmp
+#define  int_r_assign         (f_instr)eint_r_assign
+#define  int_r_plus           (f_instr)eint_r_plus
+#define  int_r_minus          (f_instr)eint_r_minus
+#define  int_r_mul            (f_instr)eint_r_mul
+#define  int_r_div            (f_instr)eint_r_div
+#define  int_r_modulo         (f_instr)eint_r_modulo
+#define  int_r_sl             (f_instr)eint_r_sl
+#define  int_r_sr             (f_instr)eint_r_sr
+#define  int_r_sand           (f_instr)eint_r_sand
+#define  int_r_sor            (f_instr)eint_r_sor
+#define  int_r_sxor           (f_instr)eint_r_sxor
+#define  int_pre_inc          (f_instr)eint_pre_inc
+#define  int_pre_dec          (f_instr)eint_pre_dec
+#define  int_post_inc         (f_instr)eint_post_inc
+#define  int_post_dec         (f_instr)eint_post_dec
+#define  FloatPlus            (f_instr)eFloatPlus
+#define  FloatMinus           (f_instr)eFloatMinus
+#define  FloatTimes           (f_instr)eFloatTimes
+#define  FloatDivide          (f_instr)eFloatDivide
+#define  float_and            (f_instr)efloat_and
+#define  float_or             (f_instr)efloat_or
+#define  float_eq             (f_instr)efloat_eq
+#define  float_neq            (f_instr)efloat_neq
+#define  float_gt             (f_instr)efloat_gt
+#define  float_ge             (f_instr)efloat_ge
+#define  float_lt             (f_instr)efloat_lt
+#define  float_le             (f_instr)efloat_le
+#define  float_negate         (f_instr)efloat_negate
+#define  float_not            (f_instr)efloat_not
+#define  float_r_assign       (f_instr)efloat_r_assign
+#define  float_r_plus         (f_instr)efloat_r_plus
+#define  float_r_minus        (f_instr)efloat_r_minus
+#define  float_r_mul          (f_instr)efloat_r_mul
+#define  float_r_div          (f_instr)efloat_r_div
+#define  int_float_plus       (f_instr)eint_float_plus
+#define  int_float_minus      (f_instr)eint_float_minus
+#define  int_float_mul        (f_instr)eint_float_mul
+#define  int_float_div        (f_instr)eint_float_div
+#define  int_float_and        (f_instr)eint_float_and
+#define  int_float_or         (f_instr)eint_float_or
+#define  int_float_eq         (f_instr)eint_float_eq
+#define  int_float_neq        (f_instr)eint_float_neq
+#define  int_float_gt         (f_instr)eint_float_gt
+#define  int_float_ge         (f_instr)eint_float_ge
+#define  int_float_lt         (f_instr)eint_float_lt
+#define  int_float_le         (f_instr)eint_float_le
+#define  int_float_r_assign   (f_instr)eint_float_r_assign
+#define  int_float_r_plus     (f_instr)eint_float_r_plus
+#define  int_float_r_minus    (f_instr)eint_float_r_minus
+#define  int_float_r_mul      (f_instr)eint_float_r_mul
+#define  int_float_r_div      (f_instr)eint_float_r_div
+#define  float_int_plus       (f_instr)efloat_int_plus
+#define  float_int_minus      (f_instr)efloat_int_minus
+#define  float_int_mul        (f_instr)efloat_int_mul
+#define  float_int_div        (f_instr)efloat_int_div
+#define  float_int_and        (f_instr)efloat_int_and
+#define  float_int_or         (f_instr)efloat_int_or
+#define  float_int_eq         (f_instr)efloat_int_eq
+#define  float_int_neq        (f_instr)efloat_int_neq
+#define  float_int_gt         (f_instr)efloat_int_gt
+#define  float_int_ge         (f_instr)efloat_int_ge
+#define  float_int_lt         (f_instr)efloat_int_lt
+#define  float_int_le         (f_instr)efloat_int_le
+#define  float_int_r_assign   (f_instr)efloat_int_r_assign
+#define  float_int_r_plus     (f_instr)efloat_int_r_plus
+#define  float_int_r_minus    (f_instr)efloat_int_r_minus
+#define  float_int_r_mul      (f_instr)efloat_int_r_mul
+#define  float_int_r_div      (f_instr)efloat_int_r_div
+#define  CastI2F              (f_instr)eCastI2F
+#define  CastF2I              (f_instr)eCastF2I
+#define  Time_Advance         (f_instr)eTime_Advance
+#define  Recurs               (f_instr)eRecurs
+#define  SetCode              (f_instr)eSetCode
+#define  RegMove              (f_instr)eRegMove
+#define  Reg2Mem              (f_instr)eReg2Mem
+#define  Reg2Mem4             (f_instr)eReg2Mem4
+#define  Overflow             (f_instr)eOverflow
+#define  FuncUsrEnd           (f_instr)eFuncUsrEnd
+#define  FuncUsrEnd2          (f_instr)eFuncUsrEnd2
+#define  FuncMemberEnd        (f_instr)eFuncMemberEnd
+#define  SporkIni             (f_instr)eSporkIni
+#define  ForkIni              (f_instr)eForkIni
+#define  SporkFunc            (f_instr)eSporkFunc
+#define  SporkMemberFptr      (f_instr)eSporkMemberFptr
+#define  SporkExp             (f_instr)eSporkExp
+#define  SporkEnd             (f_instr)eSporkEnd
+#define  BranchEqInt          (f_instr)eBranchEqInt
+#define  BranchNeqInt         (f_instr)eBranchNeqInt
+#define  BranchEqFloat        (f_instr)eBranchEqFloat
+#define  BranchNeqFloat       (f_instr)eBranchNeqFloat
+#define  Unroll               (f_instr)eUnroll
+#define  ArrayAppend          (f_instr)eArrayAppend
+#define  AutoUnrollInit       (f_instr)eAutoUnrollInit
+#define  AutoLoop             (f_instr)eAutoLoop
+#define  ArrayTop             (f_instr)eArrayTop
+#define  ArrayAccess          (f_instr)eArrayAccess
+#define  ArrayGet             (f_instr)eArrayGet
+#define  ArrayAddr            (f_instr)eArrayAddr
+#define  ObjectInstantiate    (f_instr)eObjectInstantiate
+#define  RegAddRef            (f_instr)eRegAddRef
+#define  RegAddRefAddr        (f_instr)eRegAddRefAddr
+#define  StructRegAddRef      (f_instr)eStructRegAddRef
+#define  StructRegAddRefAddr  (f_instr)eStructRegAddRefAddr
+#define  ObjectAssign         (f_instr)eObjectAssign
+#define  Assign               (f_instr)eAssign
+#define  ObjectRelease        (f_instr)eObjectRelease
+#define  GWOP_EXCEPT          (f_instr)eGWOP_EXCEPT
+#define  AllocMember4         (f_instr)eAllocMember4
+#define  DotMember            (f_instr)eDotMember
+#define  DotMember2           (f_instr)eDotMember2
+#define  DotMember3           (f_instr)eDotMember3
+#define  DotMember4           (f_instr)eDotMember4
+#define  UnionCheck           (f_instr)eUnionCheck
+#define  UnionMember          (f_instr)eUnionMember
+#define  UnionMember2         (f_instr)eUnionMember2
+#define  UnionMember3         (f_instr)eUnionMember3
+#define  UnionMember4         (f_instr)eUnionMember4
+#define  DotStatic            (f_instr)eDotStatic
+#define  DotStatic2           (f_instr)eDotStatic2
+#define  DotStatic3           (f_instr)eDotStatic3
+#define  UpvalueInt           (f_instr)eUpvalueInt
+#define  UpvalueFloat         (f_instr)eUpvalueFloat
+#define  UpvalueOther         (f_instr)eUpvalueOther
+#define  UpvalueAddr          (f_instr)eUpvalueAddr
+#define  DotFunc              (f_instr)eDotFunc
+#define  GcIni                (f_instr)eGcIni
+#define  GcAdd                (f_instr)eGcAdd
+#define  GcEnd                (f_instr)eGcEnd
+#define  GackType             (f_instr)eGackType
+#define  GackEnd              (f_instr)eGackEnd
+#define  Gack                 (f_instr)eGack
+#define  TryIni               (f_instr)eTryIni
+#define  TryEnd               (f_instr)eTryEnd
+#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
+#define  DotTmplVal           (f_instr)eDotTmplVal
+ANN static inline void dump_opcodes(const VM_Code code) {
+  gw_out("{Y}┏━━━━┓{0}{-Y} {+}%s{0}\n{Y}┃{0}\n", code->name);
+  m_uint j = 0;
+  for(m_uint i = 0; i < vector_size(&code->instr); i++) {
+    const Instr instr = (Instr)vector_at(&code->instr, i);
+    switch(instr->opcode) {
+      case eRegSetImm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegSetImm   ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushImm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushImm  ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushImm2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushImm2 ", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushImm3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushImm3 ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushImm4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushImm4 ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushMem:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMem  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushMem2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMem2 ", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushMem3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMem3 ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushMem4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMem4 ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushMemDeref:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMemDeref", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRegPushNow:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushNow  ", j);
+        gw_out("\n");
+        break;
+      case eRegPushBase:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushBase ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eRegPushBase2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushBase2", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case eRegPushBase3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushBase3", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eRegPushBase4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushBase4", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eReg2Reg:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2Reg     ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eReg2RegOther:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegOther", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eReg2RegAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegAddr ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eReg2RegDeref:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2RegDeref", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eStructMember:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructMember", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eStructMemberFloat:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructMemberFloat", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eStructMemberOther:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructMemberOther", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eStructMemberAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructMemberAddr", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eMemSetImm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: MemSetImm   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+       gw_out(" {-M}%-14p{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eMemAddImm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: MemAddImm   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"INT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRepeatIdx:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RepeatIdx   ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eRepeat:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Repeat      ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eRegPushMe:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMe   ", j);
+        gw_out("\n");
+        break;
+      case eRegPushMaybe:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegPushMaybe", j);
+        gw_out("\n");
+        break;
+      case eFuncReturn:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FuncReturn  ", j);
+        gw_out("\n");
+        break;
+      case eGoto:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Goto        ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eAllocWord:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AllocWord   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eAllocWord2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AllocWord2  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eAllocWord3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AllocWord3  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eint_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_plus    ", j);
+        gw_out("\n");
+        break;
+      case eint_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_minus   ", j);
+        gw_out("\n");
+        break;
+      case eint_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_mul     ", j);
+        gw_out("\n");
+        break;
+      case eint_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_div     ", j);
+        gw_out("\n");
+        break;
+      case eint_modulo:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_modulo  ", j);
+        gw_out("\n");
+        break;
+      case eint_eq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_eq      ", j);
+        gw_out("\n");
+        break;
+      case eint_neq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_neq     ", j);
+        gw_out("\n");
+        break;
+      case eint_and:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_and     ", j);
+        gw_out("\n");
+        break;
+      case eint_or:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_or      ", j);
+        gw_out("\n");
+        break;
+      case eint_gt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_gt      ", j);
+        gw_out("\n");
+        break;
+      case eint_ge:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_ge      ", j);
+        gw_out("\n");
+        break;
+      case eint_lt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_lt      ", j);
+        gw_out("\n");
+        break;
+      case eint_le:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_le      ", j);
+        gw_out("\n");
+        break;
+      case eint_sl:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sl      ", j);
+        gw_out("\n");
+        break;
+      case eint_sr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sr      ", j);
+        gw_out("\n");
+        break;
+      case eint_sand:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sand    ", j);
+        gw_out("\n");
+        break;
+      case eint_sor:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sor     ", j);
+        gw_out("\n");
+        break;
+      case eint_xor:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_xor     ", j);
+        gw_out("\n");
+        break;
+      case eint_negate:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_negate  ", j);
+        gw_out("\n");
+        break;
+      case eIntNot:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: IntNot      ", j);
+        gw_out("\n");
+        break;
+      case eint_cmp:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_cmp     ", j);
+        gw_out("\n");
+        break;
+      case eint_r_assign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_assign", j);
+        gw_out("\n");
+        break;
+      case eint_r_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_plus  ", j);
+        gw_out("\n");
+        break;
+      case eint_r_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_minus ", j);
+        gw_out("\n");
+        break;
+      case eint_r_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_mul   ", j);
+        gw_out("\n");
+        break;
+      case eint_r_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_div   ", j);
+        gw_out("\n");
+        break;
+      case eint_r_modulo:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_modulo", j);
+        gw_out("\n");
+        break;
+      case eint_r_sl:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_sl    ", j);
+        gw_out("\n");
+        break;
+      case eint_r_sr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_sr    ", j);
+        gw_out("\n");
+        break;
+      case eint_r_sand:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_sand  ", j);
+        gw_out("\n");
+        break;
+      case eint_r_sor:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_sor   ", j);
+        gw_out("\n");
+        break;
+      case eint_r_sxor:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_r_sxor  ", j);
+        gw_out("\n");
+        break;
+      case eint_pre_inc:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_pre_inc ", j);
+        gw_out("\n");
+        break;
+      case eint_pre_dec:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_pre_dec ", j);
+        gw_out("\n");
+        break;
+      case eint_post_inc:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_post_inc", j);
+        gw_out("\n");
+        break;
+      case eint_post_dec:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_post_dec", j);
+        gw_out("\n");
+        break;
+      case eFloatPlus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatPlus   ", j);
+        gw_out("\n");
+        break;
+      case eFloatMinus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatMinus  ", j);
+        gw_out("\n");
+        break;
+      case eFloatTimes:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatTimes  ", j);
+        gw_out("\n");
+        break;
+      case eFloatDivide:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatDivide ", j);
+        gw_out("\n");
+        break;
+      case efloat_and:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_and   ", j);
+        gw_out("\n");
+        break;
+      case efloat_or:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_or    ", j);
+        gw_out("\n");
+        break;
+      case efloat_eq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_eq    ", j);
+        gw_out("\n");
+        break;
+      case efloat_neq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_neq   ", j);
+        gw_out("\n");
+        break;
+      case efloat_gt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_gt    ", j);
+        gw_out("\n");
+        break;
+      case efloat_ge:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_ge    ", j);
+        gw_out("\n");
+        break;
+      case efloat_lt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_lt    ", j);
+        gw_out("\n");
+        break;
+      case efloat_le:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_le    ", j);
+        gw_out("\n");
+        break;
+      case efloat_negate:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_negate", j);
+        gw_out("\n");
+        break;
+      case efloat_not:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_not   ", j);
+        gw_out("\n");
+        break;
+      case efloat_r_assign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_r_assign", j);
+        gw_out("\n");
+        break;
+      case efloat_r_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_r_plus", j);
+        gw_out("\n");
+        break;
+      case efloat_r_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_r_minus", j);
+        gw_out("\n");
+        break;
+      case efloat_r_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_r_mul ", j);
+        gw_out("\n");
+        break;
+      case efloat_r_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_r_div ", j);
+        gw_out("\n");
+        break;
+      case eint_float_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_plus", j);
+        gw_out("\n");
+        break;
+      case eint_float_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_minus", j);
+        gw_out("\n");
+        break;
+      case eint_float_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_mul", j);
+        gw_out("\n");
+        break;
+      case eint_float_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_div", j);
+        gw_out("\n");
+        break;
+      case eint_float_and:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_and", j);
+        gw_out("\n");
+        break;
+      case eint_float_or:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_or", j);
+        gw_out("\n");
+        break;
+      case eint_float_eq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_eq", j);
+        gw_out("\n");
+        break;
+      case eint_float_neq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_neq", j);
+        gw_out("\n");
+        break;
+      case eint_float_gt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_gt", j);
+        gw_out("\n");
+        break;
+      case eint_float_ge:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_ge", j);
+        gw_out("\n");
+        break;
+      case eint_float_lt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_lt", j);
+        gw_out("\n");
+        break;
+      case eint_float_le:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_le", j);
+        gw_out("\n");
+        break;
+      case eint_float_r_assign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_r_assign", j);
+        gw_out("\n");
+        break;
+      case eint_float_r_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_r_plus", j);
+        gw_out("\n");
+        break;
+      case eint_float_r_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_r_minus", j);
+        gw_out("\n");
+        break;
+      case eint_float_r_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_r_mul", j);
+        gw_out("\n");
+        break;
+      case eint_float_r_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_float_r_div", j);
+        gw_out("\n");
+        break;
+      case efloat_int_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_plus", j);
+        gw_out("\n");
+        break;
+      case efloat_int_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_minus", j);
+        gw_out("\n");
+        break;
+      case efloat_int_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_mul", j);
+        gw_out("\n");
+        break;
+      case efloat_int_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_div", j);
+        gw_out("\n");
+        break;
+      case efloat_int_and:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_and", j);
+        gw_out("\n");
+        break;
+      case efloat_int_or:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_or", j);
+        gw_out("\n");
+        break;
+      case efloat_int_eq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_eq", j);
+        gw_out("\n");
+        break;
+      case efloat_int_neq:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_neq", j);
+        gw_out("\n");
+        break;
+      case efloat_int_gt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_gt", j);
+        gw_out("\n");
+        break;
+      case efloat_int_ge:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_ge", j);
+        gw_out("\n");
+        break;
+      case efloat_int_lt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_lt", j);
+        gw_out("\n");
+        break;
+      case efloat_int_le:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_le", j);
+        gw_out("\n");
+        break;
+      case efloat_int_r_assign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_r_assign", j);
+        gw_out("\n");
+        break;
+      case efloat_int_r_plus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_r_plus", j);
+        gw_out("\n");
+        break;
+      case efloat_int_r_minus:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_r_minus", j);
+        gw_out("\n");
+        break;
+      case efloat_int_r_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_r_mul", j);
+        gw_out("\n");
+        break;
+      case efloat_int_r_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_int_r_div", j);
+        gw_out("\n");
+        break;
+      case eCastI2F:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: CastI2F     ", j);
+        gw_out("\n");
+        break;
+      case eCastF2I:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: CastF2I     ", j);
+        gw_out("\n");
+        break;
+      case eTime_Advance:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Time_Advance", j);
+        gw_out("\n");
+        break;
+      case eRecurs:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Recurs      ", j);
+        gw_out("\n");
+        break;
+      case eSetCode:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SetCode     ", j);
+        gw_out("\n");
+        break;
+      case eRegMove:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegMove     ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eReg2Mem:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2Mem     ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"INT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eReg2Mem4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Reg2Mem4    ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eOverflow:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Overflow    ", j);
+        gw_out("\n");
+        break;
+      case eFuncUsrEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FuncUsrEnd  ", j);
+        gw_out("\n");
+        break;
+      case eFuncUsrEnd2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FuncUsrEnd2 ", j);
+        gw_out("\n");
+        break;
+      case eFuncMemberEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: FuncMemberEnd", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eSporkIni:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkIni    ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eForkIni:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ForkIni     ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"INT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eSporkFunc:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkFunc   ", j);
+        gw_out("\n");
+        break;
+      case eSporkMemberFptr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkMemberFptr", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eSporkExp:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkExp    ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eSporkEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: SporkEnd    ", j);
+        gw_out("\n");
+        break;
+      case eBranchEqInt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: BranchEqInt ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eBranchNeqInt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: BranchNeqInt", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eBranchEqFloat:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: BranchEqFloat", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eBranchNeqFloat:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: BranchNeqFloat", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eUnroll:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Unroll      ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eArrayAppend:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ArrayAppend ", j);
+        gw_out("\n");
+        break;
+      case eAutoUnrollInit:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AutoUnrollInit", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eAutoLoop:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AutoLoop    ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eArrayTop:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ArrayTop    ", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eArrayAccess:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ArrayAccess ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eArrayGet:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ArrayGet    ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"INT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eArrayAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ArrayAddr   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"INT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eObjectInstantiate:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ObjectInstantiate", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out(" {-B}%-14s"UINT_F"{0}", ((Type)instr->m_val2)->name);
+        gw_out("\n");
+        break;
+      case eRegAddRef:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegAddRef   ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eRegAddRefAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: RegAddRefAddr", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eStructRegAddRef:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructRegAddRef", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eStructRegAddRefAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: StructRegAddRefAddr", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eObjectAssign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ObjectAssign", j);
+        gw_out("\n");
+        break;
+      case eAssign:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Assign      ", j);
+        gw_out("\n");
+        break;
+      case eObjectRelease:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: ObjectRelease", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eGWOP_EXCEPT:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GWOP_EXCEPT ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eAllocMember4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: AllocMember4", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotMember:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotMember   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotMember2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotMember2  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotMember3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotMember3  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eDotMember4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotMember4  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eUnionCheck:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UnionCheck  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUnionMember:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UnionMember ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUnionMember2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UnionMember2", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUnionMember3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UnionMember3", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUnionMember4:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UnionMember4", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eDotStatic:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotStatic   ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotStatic2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotStatic2  ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotStatic3:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotStatic3  ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUpvalueInt:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueInt  ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eUpvalueFloat:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueFloat", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eUpvalueOther:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueOther", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eUpvalueAddr:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueAddr ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotFunc:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotFunc     ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+        gw_out("\n");
+        break;
+      case eGcIni:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GcIni       ", j);
+        gw_out("\n");
+        break;
+      case eGcAdd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GcAdd       ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eGcEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GcEnd       ", j);
+        gw_out("\n");
+        break;
+      case eGackType:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GackType    ", j);
+        gw_out("\n");
+        break;
+      case eGackEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: GackEnd     ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eGack:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Gack        ", j);
+        gw_out("\n");
+        break;
+      case eTryIni:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: TryIni      ", j);
+        gw_out("\n");
+        break;
+      case eTryEnd:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: TryEnd      ", j);
+        gw_out("\n");
+        break;
+      case eHandleEffect:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: HandleEffect", j);
+        gw_out(" {-B}=>%-12"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case ePerformEffect:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: PerformEffect", j);
+        gw_out("\n");
+        break;
+      case eNoOp:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: NoOp        ", j);
+        gw_out("\n");
+        break;
+      case eDebugLine:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DebugLine   ", j);
+        gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDebugValue:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DebugValue  ", j);
+        gw_out("\n");
+        break;
+      case eDebugPush:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DebugPush   ", j);
+        gw_out("\n");
+        break;
+      case eDebugPop:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DebugPop    ", j);
+        gw_out("\n");
+        break;
+      case eEOC:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: EOC         ", j);
+        gw_out("\n");
+        break;
+      case eUnroll2:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: Unroll2     ", j);
+        gw_out("\n");
+        break;
+      case eOP_MAX:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: OP_MAX      ", j);
+        gw_out(" {-R}%-14p{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eDotTmplVal:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: DotTmplVal  ", j);
+        gw_out("\n");
+        break;
+    }
+    j++;
+  }
+  gw_out("{Y}┃\n┗━━━━┛{0}\n");
+}
 #endif
index 777e33ee90a178cf51b25f84dac6bb0edeb30f55..9922c002bbb253df3ea08c8c02ecb0dcbcd6c7f7 100644 (file)
@@ -100,7 +100,7 @@ REF_FUNC(VM_Code, vmcode)
 ANN2(1, 4)
 ANEW VM_Code     new_vmcode(MemPool p, const Vector instr,
                             const M_Vector live_values, const m_str name,
-                            const uint16_t stack_depth, const bool builtin);
+                            const uint16_t stack_depth, const bool builtin, const bool dump);
 ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code);
 
 ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
index 169fa167bd5aa1456d845cc7a54ecd345dab8365..796e058edf2ee74c38279b90a4ef610c48095165 100644 (file)
@@ -1,37 +1,37 @@
-RegSetImm
-RegPushImm
-RegPushImm2
-RegPushImm3
-RegPushImm4
-RegPushMem
-RegPushMem2
-RegPushMem3
-RegPushMem4
-RegPushMemDeref
+RegSetImm~p~u
+RegPushImm~p~u
+RegPushImm2~f~u
+RegPushImm3~p~u
+RegPushImm4~p~u
+RegPushMem~u~u
+RegPushMem2~f~u
+RegPushMem3~u~u
+RegPushMem4~u~u
+RegPushMemDeref~u~u
 RegPushNow
-RegPushBase
-RegPushBase2
-RegPushBase3
-RegPushBase4
-Reg2Reg
-Reg2RegOther
-Reg2RegAddr
-Reg2RegDeref
-StructMember
-StructMemberFloat
-StructMemberOther
-StructMemberAddr
-MemSetImm
-MemAddImm
-RepeatIdx
-Repeat
+RegPushBase~p
+RegPushBase2~f
+RegPushBase3~p
+RegPushBase4~p
+Reg2Reg~u~u
+Reg2RegOther~u~u
+Reg2RegAddr~u~u
+Reg2RegDeref~u~u
+StructMember~u
+StructMemberFloat~u
+StructMemberOther~u
+StructMemberAddr~u
+MemSetImm~u~p
+MemAddImm~u~i
+RepeatIdx~pc~u
+Repeat~pc
 RegPushMe
 RegPushMaybe
 FuncReturn
-Goto
-AllocWord
-AllocWord2
-AllocWord3
+Goto~pc
+AllocWord~u
+AllocWord2~u
+AllocWord3~u~u
 int_plus
 int_minus
 int_mul
@@ -126,74 +126,74 @@ CastF2I
 Time_Advance
 Recurs
 SetCode
-RegMove
-Reg2Mem
-Reg2Mem4
+RegMove~i
+Reg2Mem~u~i
+Reg2Mem4~u~u
 Overflow
 FuncUsrEnd
 FuncUsrEnd2
-FuncMemberEnd
-SporkIni
-ForkIni
+FuncMemberEnd~u~↓
+SporkIni~p
+ForkIni~p~i
 SporkFunc
-SporkMemberFptr
-SporkExp
+SporkMemberFptr~u
+SporkExp~u
 SporkEnd
-BranchEqInt
-BranchNeqInt
-BranchEqFloat
-BranchNeqFloat
-Unroll
+BranchEqInt~pc
+BranchNeqInt~pc
+BranchEqFloat~pc
+BranchNeqFloat~pc
+Unroll~u~u
 ArrayAppend
-AutoUnrollInit
-AutoLoop
-ArrayTop
-ArrayAccess
-ArrayGet
-ArrayAddr
-ObjectInstantiate
-RegAddRef
-RegAddRefAddr
-StructRegAddRef
-StructRegAddRefAddr
+AutoUnrollInit~u
+AutoLoop~pc
+ArrayTop~pc
+ArrayAccess~u~u
+ArrayGet~u~i
+ArrayAddr~u~i
+ObjectInstantiate~i~t
+RegAddRef~i
+RegAddRefAddr~i
+StructRegAddRef~i~u
+StructRegAddRefAddr~i
 ObjectAssign
 Assign
-ObjectRelease
-GWOP_EXCEPT
-AllocMember4
-DotMember
-DotMember2
-DotMember3
-DotMember4
-UnionCheck
-UnionMember
-UnionMember2
-UnionMember3
-UnionMember4
-DotStatic
-DotStatic2
-DotStatic3
-UpvalueInt
-UpvalueFloat
-UpvalueOther
-UpvalueAddr
-DotFunc
+ObjectRelease~u
+GWOP_EXCEPT~u
+AllocMember4~u
+DotMember~u
+DotMember2~u
+DotMember3~u~u
+DotMember4~u
+UnionCheck~u~u
+UnionMember~u~u
+UnionMember2~u~u
+UnionMember3~u~u
+UnionMember4~u~u
+DotStatic~p
+DotStatic2~p
+DotStatic3~p~u
+UpvalueInt~u
+UpvalueFloat~u
+UpvalueOther~u~u
+UpvalueAddr~u
+DotFunc~u~u
 GcIni
-GcAdd
+GcAdd~i
 GcEnd
 GackType
-GackEnd
+GackEnd~u
 Gack
 TryIni
 TryEnd
-HandleEffect
+HandleEffect~pc
 PerformEffect
 NoOp
-DebugLine
+DebugLine~u
 DebugValue
 DebugPush
 DebugPop
 EOC
 Unroll2
-OP_MAX
+OP_MAX~p
 DotTmplVal
diff --git a/plug b/plug
index 4e20d4f6797233970ccc89a422b716a0d26285ee..a982b4368dc4a90c46c7e20aecbf6a2c69cd7839 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit 4e20d4f6797233970ccc89a422b716a0d26285ee
+Subproject commit a982b4368dc4a90c46c7e20aecbf6a2c69cd7839
index 356076815640d161795481688f104e84a382e61b..1d79cd1488eb13dec9efe25cf6fe0d98828a86db 100644 (file)
@@ -2,11 +2,12 @@
 echo "#ifndef __GWION_OPCODES__"
 echo "#define __GWION_OPCODES__"
 
-list=$(grep -v "#" opcode.txt)
+list="$(grep -v "#" opcode.txt)"
 COUNT=0
 echo "enum {"
-for a in ${list}
+for info in ${list}
 do
+  a=$(echo "$info" | cut -f1 -d"~")
   [ -z "$a" ] || {
     echo "  e$a,"
     COUNT=$((COUNT+1))
@@ -15,11 +16,68 @@ done
 echo "};"
 echo ""
 
-for a in ${list}
+print_arg1() {
+  if [ "$1" = "p" ]
+  then echo "        gw_out(\" {-R}%-14p{0}\", instr->m_val);"
+  elif [ "$1" = "u" ]
+  then echo "        gw_out(\" {-R}%-14\"UINT_F\"{0}\", instr->m_val);"
+  elif [ "$1" = "i" ]
+  then echo "        gw_out(\" {-R}%-14\"INT_F\"{0}\", instr->m_val);"
+  elif [ "$1" = "f" ]
+  then echo "        gw_out(\" {-R}%-14f\", instr->f);"
+  elif [ "$1" = "pc" ]
+  then echo "        gw_out(\" {-B}=>%-12\"UINT_F\"{0}\", instr->m_val);"
+  elif [ "$1" = "t" ]
+  then echo "        gw_out(\" {-B}%-14s\"UINT_F\"{0}\", ((Type)instr->m_val)->name);"
+  fi
+}
+
+print_arg2() {
+  if [ "$1" = "p" ]
+  then  echo "       gw_out(\" {-M}%-14p{0}\", instr->m_val2);"
+  elif [ "$1" = "u" ]
+  then echo "        gw_out(\" {-M}%-14\"UINT_F\"{0}\", instr->m_val2);"
+  elif [ "$1" = "i" ]
+  then echo "        gw_out(\" {-M}%-14\"INT_F\"{0}\", instr->m_val2);"
+  elif [ "$1" = "t" ]
+  then echo "        gw_out(\" {-B}%-14s\"UINT_F\"{0}\", ((Type)instr->m_val2)->name);"
+  fi
+}
+
+for info in ${list}
 do
+  a=$(echo "$info" | cut -f1 -d"~")
   [ -z "$a" ] || echo "#define  $a (f_instr)e$a"
 done | column -t
 
+echo "ANN static inline void dump_opcodes(const VM_Code code) {"
+echo "  gw_out(\"{Y}┏━━━━┓{0}{-Y} {+}%s{0}\n{Y}┃{0}\n\", code->name);"
+echo "  m_uint j = 0;"
+echo "  for(m_uint i = 0; i < vector_size(&code->instr); i++) {"
+echo "    const Instr instr = (Instr)vector_at(&code->instr, i);"
+echo "    switch(instr->opcode) {"
+for info in ${list}
+do
+  a=$(echo "$info" | cut -f1 -d"~")
+#  [ -z "$a" ] && continue
+  val1=$(echo "$info" | cut -f2 -d"~")
+  [ "$val1" = "$a" ] && val1=""
+  val2=$(echo "$info" | cut -f3 -d"~")
+  [ "$val2" = "$a" ] && val2=""
+  formatted="$(printf '%-12s' $a)"
+  #printf "    case e$a:\n     gw_out(\"{Y}┃{0}{-}%% 4lu{0}: $formatted\", j);\n"
+  printf '      case e%s:\n        gw_out(\"{Y}┃{0}{-}%% 4lu{0}: %s\", j);\n' "$a" "$formatted"
+  [ -z "$val1" ] || print_arg1 "$val1"
+  [ -z "$val2" ] || print_arg2 "$val2"
+  echo "        gw_out(\"\n\");"
+  printf '        break;\n'
+done
+echo "    }"
+echo "    j++;"
+echo "  }"
+echo "  gw_out(\"{Y}┃\n┗━━━━┛{0}\n\");"
+echo "}"
+
 echo "#endif"
 
 echo "generated" "$COUNT" "opcodes" >&2
index 2157e6700db0ae894e5c92be602f2aa92f1600a1..cce495dbb94eb7de2be5912a842390bcb19b1dee 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -29,6 +29,7 @@ enum {
   UNDEF,
   INCLUDE,
   DEBUG,
+  DUMP,
   CDOC,
   NOPTIONS
 };
@@ -60,7 +61,8 @@ enum arg_type {
   ARG_UNDEF,
   ARG_INCLUDE,
   ARG_DEBUG,
-  ARG_CDOC
+  ARG_DUMP,
+  ARG_CDOC,
 };
 
 ANN static void arg_init(Arg *arg) {
@@ -92,6 +94,11 @@ ANN static inline void get_debug(const Gwion gwion, const char *dbg) {
   gwion_set_debug(gwion, is_dbg);
 }
 
+ANN static inline void get_dump(const Gwion gwion, const char *dbg) {
+  const bool is_dbg = str2bool(dbg);
+  gwion_set_dump(gwion, is_dbg);
+}
+
 ANN static inline void get_cdoc(const Gwion gwion, const char *cdoc) {
   const bool is_cdoc = str2bool(cdoc);
   gwion_set_cdoc(gwion, is_cdoc);
@@ -119,6 +126,9 @@ ANN void arg_compile(const Gwion gwion, Arg *arg) {
     case ARG_DEBUG:
       get_debug(gwion, (m_str)VPTR(v, ++i));
       break;
+    case ARG_DUMP:
+      get_debug(gwion, (m_str)VPTR(v, ++i));
+      break;
     }
   }
 }
@@ -172,6 +182,8 @@ static void setup_options(cmdapp_t *app, cmdopt_t *opt) {
              "add ARG to include path", &opt[INCLUDE]);
   cmdapp_set(app, 'G', "debug", CMDOPT_MAYTAKEARG, NULL, "set/unset debug mode",
              &opt[DEBUG]);
+  cmdapp_set(app, 'B', "dump", CMDOPT_MAYTAKEARG, NULL, "set/unset bytecode dump",
+             &opt[DUMP]);
   cmdapp_set(app, 'H', "cdoc", CMDOPT_MAYTAKEARG, NULL, "set/unset cdoc mode",
              &opt[CDOC]);
 }
@@ -295,6 +307,9 @@ static void myproc(void *data, cmdopt_t *option, const char *arg) {
     case 'G':
       add2arg(_arg, option->value, ARG_DEBUG);
       break;
+    case 'B':
+      get_dump(arg_int->gwion, option->value);
+      break;
     case 'H':
       get_cdoc(arg_int->gwion, option->value);
       break;
index 7f6c9075b950c8ad10c496a716237819818b2ca9..82026861e6981e234c42fc60b7be5704726937e0 100644 (file)
@@ -12,7 +12,7 @@ static ANEW ANN VM_Code emit_code(const Emitter emit) {
   const bool    has_values = m_vector_size(&c->live_values);
   const VM_Code code       = new_vmcode(emit->gwion->mp, &c->instr,
                                   has_values ? &c->live_values : NULL, c->name,
-                                  c->stack_depth, false);
+                                  c->stack_depth, false, emit->info->dump);
   if (has_values) c->live_values.ptr = NULL;
   return code;
 }
index 591db4bda75b01e9ca4b56b58b7328725cd55d66..3dc20b348d46e6b63d1504c17d743530d2456199 100644 (file)
@@ -37,7 +37,7 @@ Symbol func_symbol(const Env env, const m_str nspc, const m_str base,
 
 ANN void builtin_func(const MemPool mp, const Func f, void *func_ptr) {
   set_vflag(f->value_ref, vflag_builtin);
-  f->code = new_vmcode(mp, NULL, NULL, f->name, f->def->stack_depth, true);
+  f->code = new_vmcode(mp, NULL, NULL, f->name, f->def->stack_depth, true, false);
   f->code->native_func = (m_uint)func_ptr;
   f->code->ret_type = f->def->base->ret_type;
 }
index adbd7f89693cfe5e7c2879fa045cdca2df446ac2..8c594e195b31583ba835b2d3dc27be5687686927 100644 (file)
@@ -34,7 +34,7 @@ ANN static inline m_bool gwion_engine(const Gwion gwion) {
 
 ANN static void gwion_cleaner(const Gwion gwion) {
   const VM_Code code =
-      new_vmcode(gwion->mp, NULL, NULL, "in code dtor", 0, true);
+      new_vmcode(gwion->mp, NULL, NULL, "in code dtor", 0, true, false);
   gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
   vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
 }
@@ -218,6 +218,9 @@ ANN Nspc pop_global(struct Gwion_ *gwion) {
 ANN void gwion_set_debug(const Gwion gwion, const bool dbg) {
   gwion->emit->info->debug = dbg;
 }
+ANN void gwion_set_dump(const Gwion gwion, const bool dump) {
+  gwion->emit->info->dump = dump;
+}
 ANN void gwion_set_cdoc(const Gwion gwion, const bool cdoc) {
   gwion->data->cdoc = cdoc;
 }
index 05daf682f82bb95c9f378a5c0ca163294e828035..ee5a1dad57bdf31a57a78bb40d34226980e02e31 100644 (file)
@@ -21,7 +21,7 @@ ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d,
                           const enum tflag e) {
   VM_Code *code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
   const m_str name     = type->name;
-  *code                = new_vmcode(p, NULL, NULL, name, SZ_INT, true);
+  *code                = new_vmcode(p, NULL, NULL, name, SZ_INT, true, false);
   (*code)->native_func = (m_uint)d;
   type->tflag |= e;
   return GW_OK;
index d0586769138f3923a5e0b12db6b2e02a66b8b746..bcef3eb15b401c842cd6417ed21998e9623ee89e 100644 (file)
@@ -45,7 +45,7 @@ ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) {
 }
 
 ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
-  const VM_Code code = new_vmcode(p, NULL, NULL, "@gack", SZ_INT, true);
+  const VM_Code code = new_vmcode(p, NULL, NULL, "@gack", SZ_INT, true, false);
   code->native_func  = (m_uint)d;
   type->info->gack   = code;
   return GW_OK;
index c3c38f895053042102e77c7cf1e5c5c9a605c7cb..e8842a6034bd953ea047c63ea395791b0946658f 100644 (file)
@@ -711,7 +711,7 @@ static OP_CHECK(opck_array_scan) {
                vm_vector_foldr);
   if (isa(base, env->gwion->type[et_compound]) > 0) {
     t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, NULL,
-                               "array component dtor", SZ_INT, true);
+                               "array component dtor", SZ_INT, true, false);
     set_tflag(t, tflag_dtor);
     t->nspc->dtor->native_func = (m_uint)(
         !tflag(base, tflag_struct) ? array_dtor_obj : array_dtor_struct);
index b7b1ea7ba70394ba6cf4af519da0c3351e387cd6..52b522a378353528ad63b3997ac37a358db4b37a 100644 (file)
@@ -159,7 +159,7 @@ static OP_CHECK(opck_ptr_scan) {
   nspc_add_type_front(t->info->value->from->owner, info.name, t);
   if (isa(base, env->gwion->type[et_compound]) > 0) {
     t->nspc->dtor =
-        new_vmcode(env->gwion->mp, NULL, NULL, "@PtrDtor", SZ_INT, true);
+        new_vmcode(env->gwion->mp, NULL, NULL, "@PtrDtor", SZ_INT, true, false);
     if (!tflag(base, tflag_struct))
       t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
     else
index 1178633ec0bcbbba03ffd1fb46c60617e1b92172..48191711f5a548cc3e195ffab233b740d589f42c 100644 (file)
@@ -155,7 +155,7 @@ ANN static m_bit *tobytecode(MemPool p, const VM_Code code) {
 
 VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values,
                    const m_str name, const uint16_t stack_depth,
-                   const bool builtin) {
+                   const bool builtin, const bool dump) {
   VM_Code code = mp_calloc(p, VM_Code);
   code->name   = mstrdup(p, name);
   if (instr) {
@@ -167,6 +167,7 @@ VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values,
   code->stack_depth = stack_depth;
   code->builtin     = builtin;
   code->ref         = 1;
+  if (dump) dump_opcodes(code);
   return code;
 }
 
@@ -178,7 +179,7 @@ VM_Code vmcode_callback(MemPool mp, VM_Code base) {
   const Instr instr  = (Instr)vector_back(&base->instr);
   instr->opcode      = eEOC;
   const VM_Code code = new_vmcode(mp, &base->instr, &base->live_values, name,
-                                  base->stack_depth, base->builtin);
+                                  base->stack_depth, base->builtin, false);
   code->closure      = base->closure;
   code->callback     = 1;
   instr->opcode      = eFuncReturn;