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
shred->pc = pc; // VKEY(m, i);
vector_pop(&shred->info->frame);
vector_pop(&shred->info->frame);
-// return false;
return true;
}
#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; \
#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; \
_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();
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[] = {
&®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr,
&®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr,
&&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline,
&&debugvalue, &&debugpush, &&debugpop, &&eoc, &&unroll2, &&other,
&®pushimm};
- 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:
}
DISPATCH();
setcode:
- PRAGMA_PUSH()
a.code = *(VM_Code *)(reg - SZ_INT);
if (!a.code->builtin) {
register const uint push =
mem += *(m_uint *)reg;
next = eFuncMemberEnd;
}
- PRAGMA_POP()
regmove:
reg += IVAL;
DISPATCH();
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;
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);
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;
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);
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:
}
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()
}
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)&®pushimm;
+ 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