serializable code representation
This commit is contained in:
parent
600a92835e
commit
1fbc38fe55
|
@ -701,15 +701,15 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
|
||||||
#define emit_i(pic, cxt, ins, I) do { \
|
#define emit_i(pic, cxt, ins, I) do { \
|
||||||
check_code_size(pic, cxt); \
|
check_code_size(pic, cxt); \
|
||||||
cxt->code[cxt->clen].insn = ins; \
|
cxt->code[cxt->clen].insn = ins; \
|
||||||
cxt->code[cxt->clen].u.i = I; \
|
cxt->code[cxt->clen].a = I; \
|
||||||
cxt->clen++; \
|
cxt->clen++; \
|
||||||
} while (0) \
|
} while (0) \
|
||||||
|
|
||||||
#define emit_r(pic, cxt, ins, D, I) do { \
|
#define emit_r(pic, cxt, ins, D, I) do { \
|
||||||
check_code_size(pic, cxt); \
|
check_code_size(pic, cxt); \
|
||||||
cxt->code[cxt->clen].insn = ins; \
|
cxt->code[cxt->clen].insn = ins; \
|
||||||
cxt->code[cxt->clen].u.r.depth = D; \
|
cxt->code[cxt->clen].a = D; \
|
||||||
cxt->code[cxt->clen].u.r.idx = I; \
|
cxt->code[cxt->clen].b = I; \
|
||||||
cxt->clen++; \
|
cxt->clen++; \
|
||||||
} while (0) \
|
} while (0) \
|
||||||
|
|
||||||
|
@ -912,11 +912,11 @@ codegen_if(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos)
|
||||||
|
|
||||||
emit_n(pic, cxt, OP_JMP);
|
emit_n(pic, cxt, OP_JMP);
|
||||||
|
|
||||||
cxt->code[s].u.i = (int)cxt->clen - s;
|
cxt->code[s].a = (int)cxt->clen - s;
|
||||||
|
|
||||||
/* if true branch */
|
/* if true branch */
|
||||||
codegen(pic, cxt, pic_list_ref(pic, obj, 2), tailpos);
|
codegen(pic, cxt, pic_list_ref(pic, obj, 2), tailpos);
|
||||||
cxt->code[t].u.i = (int)cxt->clen - t;
|
cxt->code[t].a = (int)cxt->clen - t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -11,13 +11,8 @@ extern "C" {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int insn;
|
int insn;
|
||||||
union {
|
int a;
|
||||||
int i;
|
int b;
|
||||||
struct {
|
|
||||||
int depth;
|
|
||||||
int idx;
|
|
||||||
} r;
|
|
||||||
} u;
|
|
||||||
} pic_code;
|
} pic_code;
|
||||||
|
|
||||||
struct pic_list {
|
struct pic_list {
|
||||||
|
|
|
@ -52,7 +52,7 @@ enum pic_opcode {
|
||||||
|
|
||||||
#define PIC_INIT_CODE_I(code, op, ival) do { \
|
#define PIC_INIT_CODE_I(code, op, ival) do { \
|
||||||
code.insn = op; \
|
code.insn = op; \
|
||||||
code.u.i = ival; \
|
code.a = ival; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -80,52 +80,52 @@ pic_dump_code(pic_code c)
|
||||||
puts("OP_PUSHFALSE");
|
puts("OP_PUSHFALSE");
|
||||||
break;
|
break;
|
||||||
case OP_PUSHINT:
|
case OP_PUSHINT:
|
||||||
printf("OP_PUSHINT\t%d\n", c.u.i);
|
printf("OP_PUSHINT\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_PUSHCHAR:
|
case OP_PUSHCHAR:
|
||||||
printf("OP_PUSHCHAR\t%c\n", c.u.c);
|
printf("OP_PUSHCHAR\t%c\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_PUSHCONST:
|
case OP_PUSHCONST:
|
||||||
printf("OP_PUSHCONST\t%d\n", c.u.i);
|
printf("OP_PUSHCONST\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_GREF:
|
case OP_GREF:
|
||||||
printf("OP_GREF\t%i\n", c.u.i);
|
printf("OP_GREF\t%i\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_GSET:
|
case OP_GSET:
|
||||||
printf("OP_GSET\t%i\n", c.u.i);
|
printf("OP_GSET\t%i\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_LREF:
|
case OP_LREF:
|
||||||
printf("OP_LREF\t%d\n", c.u.i);
|
printf("OP_LREF\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_LSET:
|
case OP_LSET:
|
||||||
printf("OP_LSET\t%d\n", c.u.i);
|
printf("OP_LSET\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_CREF:
|
case OP_CREF:
|
||||||
printf("OP_CREF\t%d\t%d\n", c.u.r.depth, c.u.r.idx);
|
printf("OP_CREF\t%d\t%d\n", c.a, c.b);
|
||||||
break;
|
break;
|
||||||
case OP_CSET:
|
case OP_CSET:
|
||||||
printf("OP_CSET\t%d\t%d\n", c.u.r.depth, c.u.r.idx);
|
printf("OP_CSET\t%d\t%d\n", c.a, c.b);
|
||||||
break;
|
break;
|
||||||
case OP_JMP:
|
case OP_JMP:
|
||||||
printf("OP_JMP\t%x\n", c.u.i);
|
printf("OP_JMP\t%x\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_JMPIF:
|
case OP_JMPIF:
|
||||||
printf("OP_JMPIF\t%x\n", c.u.i);
|
printf("OP_JMPIF\t%x\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_NOT:
|
case OP_NOT:
|
||||||
puts("OP_NOT");
|
puts("OP_NOT");
|
||||||
break;
|
break;
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
printf("OP_CALL\t%d\n", c.u.i);
|
printf("OP_CALL\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_TAILCALL:
|
case OP_TAILCALL:
|
||||||
printf("OP_TAILCALL\t%d\n", c.u.i);
|
printf("OP_TAILCALL\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_RET:
|
case OP_RET:
|
||||||
puts("OP_RET");
|
puts("OP_RET");
|
||||||
break;
|
break;
|
||||||
case OP_LAMBDA:
|
case OP_LAMBDA:
|
||||||
printf("OP_LAMBDA\t%d\n", c.u.i);
|
printf("OP_LAMBDA\t%d\n", c.a);
|
||||||
break;
|
break;
|
||||||
case OP_CONS:
|
case OP_CONS:
|
||||||
puts("OP_CONS");
|
puts("OP_CONS");
|
||||||
|
|
|
@ -378,7 +378,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
|
|
||||||
/* boot! */
|
/* boot! */
|
||||||
boot[0].insn = OP_CALL;
|
boot[0].insn = OP_CALL;
|
||||||
boot[0].u.i = argc + 1;
|
boot[0].a = argc + 1;
|
||||||
boot[1].insn = OP_STOP;
|
boot[1].insn = OP_STOP;
|
||||||
pic->ip = boot;
|
pic->ip = boot;
|
||||||
|
|
||||||
|
@ -407,23 +407,23 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_PUSHINT) {
|
CASE(OP_PUSHINT) {
|
||||||
PUSH(pic_int_value(pic->ci->irep->ints[c.u.i]));
|
PUSH(pic_int_value(pic->ci->irep->ints[c.a]));
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_PUSHCHAR) {
|
CASE(OP_PUSHCHAR) {
|
||||||
PUSH(pic_char_value(pic->ci->irep->ints[c.u.i]));
|
PUSH(pic_char_value(pic->ci->irep->ints[c.a]));
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_PUSHCONST) {
|
CASE(OP_PUSHCONST) {
|
||||||
PUSH(pic->ci->irep->pool[c.u.i]);
|
PUSH(pic->ci->irep->pool[c.a]);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GREF) {
|
CASE(OP_GREF) {
|
||||||
PUSH(vm_gref(pic, pic_box_ptr(pic->ci->irep->pool[c.u.i]), NULL)); /* FIXME */
|
PUSH(vm_gref(pic, pic_box_ptr(pic->ci->irep->pool[c.a]), NULL)); /* FIXME */
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_GSET) {
|
CASE(OP_GSET) {
|
||||||
vm_gset(pic_box_ptr(pic->ci->irep->pool[c.u.i]), POP());
|
vm_gset(pic_box_ptr(pic->ci->irep->pool[c.a]), POP());
|
||||||
PUSH(pic_undef_value());
|
PUSH(pic_undef_value());
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
@ -432,12 +432,12 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
struct pic_irep *irep = ci->irep;
|
struct pic_irep *irep = ci->irep;
|
||||||
|
|
||||||
if (ci->cxt != NULL && ci->cxt->regs == ci->cxt->storage) {
|
if (ci->cxt != NULL && ci->cxt->regs == ci->cxt->storage) {
|
||||||
if (c.u.i >= irep->argc + irep->localc) {
|
if (c.a >= irep->argc + irep->localc) {
|
||||||
PUSH(ci->cxt->regs[c.u.i - (ci->regs - ci->fp)]);
|
PUSH(ci->cxt->regs[c.a - (ci->regs - ci->fp)]);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PUSH(pic->ci->fp[c.u.i]);
|
PUSH(pic->ci->fp[c.a]);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_LSET) {
|
CASE(OP_LSET) {
|
||||||
|
@ -445,41 +445,41 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
struct pic_irep *irep = ci->irep;
|
struct pic_irep *irep = ci->irep;
|
||||||
|
|
||||||
if (ci->cxt != NULL && ci->cxt->regs == ci->cxt->storage) {
|
if (ci->cxt != NULL && ci->cxt->regs == ci->cxt->storage) {
|
||||||
if (c.u.i >= irep->argc + irep->localc) {
|
if (c.a >= irep->argc + irep->localc) {
|
||||||
ci->cxt->regs[c.u.i - (ci->regs - ci->fp)] = POP();
|
ci->cxt->regs[c.a - (ci->regs - ci->fp)] = POP();
|
||||||
PUSH(pic_undef_value());
|
PUSH(pic_undef_value());
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pic->ci->fp[c.u.i] = POP();
|
pic->ci->fp[c.a] = POP();
|
||||||
PUSH(pic_undef_value());
|
PUSH(pic_undef_value());
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_CREF) {
|
CASE(OP_CREF) {
|
||||||
int depth = c.u.r.depth;
|
int depth = c.a;
|
||||||
struct pic_context *cxt;
|
struct pic_context *cxt;
|
||||||
|
|
||||||
cxt = pic->ci->up;
|
cxt = pic->ci->up;
|
||||||
while (--depth) {
|
while (--depth) {
|
||||||
cxt = cxt->up;
|
cxt = cxt->up;
|
||||||
}
|
}
|
||||||
PUSH(cxt->regs[c.u.r.idx]);
|
PUSH(cxt->regs[c.b]);
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_CSET) {
|
CASE(OP_CSET) {
|
||||||
int depth = c.u.r.depth;
|
int depth = c.a;
|
||||||
struct pic_context *cxt;
|
struct pic_context *cxt;
|
||||||
|
|
||||||
cxt = pic->ci->up;
|
cxt = pic->ci->up;
|
||||||
while (--depth) {
|
while (--depth) {
|
||||||
cxt = cxt->up;
|
cxt = cxt->up;
|
||||||
}
|
}
|
||||||
cxt->regs[c.u.r.idx] = POP();
|
cxt->regs[c.b] = POP();
|
||||||
PUSH(pic_undef_value());
|
PUSH(pic_undef_value());
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_JMP) {
|
CASE(OP_JMP) {
|
||||||
pic->ip += c.u.i;
|
pic->ip += c.a;
|
||||||
JUMP;
|
JUMP;
|
||||||
}
|
}
|
||||||
CASE(OP_JMPIF) {
|
CASE(OP_JMPIF) {
|
||||||
|
@ -487,7 +487,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
|
|
||||||
v = POP();
|
v = POP();
|
||||||
if (! pic_false_p(v)) {
|
if (! pic_false_p(v)) {
|
||||||
pic->ip += c.u.i;
|
pic->ip += c.a;
|
||||||
JUMP;
|
JUMP;
|
||||||
}
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
|
@ -496,13 +496,13 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
pic_value x, v;
|
pic_value x, v;
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
|
|
||||||
if (c.u.i == -1) {
|
if (c.a == -1) {
|
||||||
pic->sp += pic->ci[1].retc - 1;
|
pic->sp += pic->ci[1].retc - 1;
|
||||||
c.u.i = pic->ci[1].retc + 1;
|
c.a = pic->ci[1].retc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
L_CALL:
|
L_CALL:
|
||||||
x = pic->sp[-c.u.i];
|
x = pic->sp[-c.a];
|
||||||
if (! pic_proc_p(x)) {
|
if (! pic_proc_p(x)) {
|
||||||
pic_errorf(pic, "invalid application: ~s", x);
|
pic_errorf(pic, "invalid application: ~s", x);
|
||||||
}
|
}
|
||||||
|
@ -515,10 +515,10 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
ci = PUSHCI();
|
ci = PUSHCI();
|
||||||
ci->argc = c.u.i;
|
ci->argc = c.a;
|
||||||
ci->retc = 1;
|
ci->retc = 1;
|
||||||
ci->ip = pic->ip;
|
ci->ip = pic->ip;
|
||||||
ci->fp = pic->sp - c.u.i;
|
ci->fp = pic->sp - c.a;
|
||||||
ci->irep = NULL;
|
ci->irep = NULL;
|
||||||
ci->cxt = NULL;
|
ci->cxt = NULL;
|
||||||
if (pic_proc_func_p(proc)) {
|
if (pic_proc_func_p(proc)) {
|
||||||
|
@ -581,12 +581,12 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
vm_tear_off(pic->ci);
|
vm_tear_off(pic->ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.u.i == -1) {
|
if (c.a == -1) {
|
||||||
pic->sp += pic->ci[1].retc - 1;
|
pic->sp += pic->ci[1].retc - 1;
|
||||||
c.u.i = pic->ci[1].retc + 1;
|
c.a = pic->ci[1].retc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
argc = c.u.i;
|
argc = c.a;
|
||||||
argv = pic->sp - argc;
|
argv = pic->sp - argc;
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
pic->ci->fp[i] = argv[i];
|
pic->ci->fp[i] = argv[i];
|
||||||
|
@ -629,7 +629,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
vm_push_cxt(pic);
|
vm_push_cxt(pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc = pic_make_proc_irep(pic, pic->ci->irep->irep[c.u.i], pic->ci->cxt);
|
proc = pic_make_proc_irep(pic, pic->ci->irep->irep[c.a], pic->ci->cxt);
|
||||||
PUSH(pic_obj_value(proc));
|
PUSH(pic_obj_value(proc));
|
||||||
pic_gc_arena_restore(pic, ai);
|
pic_gc_arena_restore(pic, ai);
|
||||||
NEXT;
|
NEXT;
|
||||||
|
@ -638,7 +638,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, int argc, pic_value *argv)
|
||||||
#define check_condition(name, n) do { \
|
#define check_condition(name, n) do { \
|
||||||
if (! pic_eq_p(pic->p##name, pic->c##name->value)) \
|
if (! pic_eq_p(pic->p##name, pic->c##name->value)) \
|
||||||
goto L_CALL; \
|
goto L_CALL; \
|
||||||
if (c.u.i != n + 1) \
|
if (c.a != n + 1) \
|
||||||
goto L_CALL; \
|
goto L_CALL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue