[bugfix] codegen causes segv when default irep size is short
This commit is contained in:
parent
9885bdd982
commit
bb55bbfdde
|
@ -144,22 +144,17 @@ static bool
|
||||||
push_scope(analyze_state *state, pic_value formals)
|
push_scope(analyze_state *state, pic_value formals)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
analyze_scope *scope;
|
analyze_scope *scope = pic_alloc(pic, sizeof(analyze_scope));
|
||||||
bool varg;
|
bool varg;
|
||||||
xvect args, locals, captures;
|
|
||||||
|
|
||||||
xv_init(args);
|
xv_init(scope->args);
|
||||||
xv_init(locals);
|
xv_init(scope->locals);
|
||||||
xv_init(captures);
|
xv_init(scope->captures);
|
||||||
|
|
||||||
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
if (analyze_args(pic, formals, &varg, &scope->args, &scope->locals)) {
|
||||||
scope = pic_alloc(pic, sizeof(analyze_scope));
|
|
||||||
scope->up = state->scope;
|
scope->up = state->scope;
|
||||||
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
||||||
scope->varg = varg;
|
scope->varg = varg;
|
||||||
scope->args = args;
|
|
||||||
scope->locals = locals;
|
|
||||||
scope->captures = captures;
|
|
||||||
scope->defer = pic_nil_value();
|
scope->defer = pic_nil_value();
|
||||||
|
|
||||||
state->scope = scope;
|
state->scope = scope;
|
||||||
|
@ -167,8 +162,10 @@ push_scope(analyze_state *state, pic_value formals)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xv_destroy(args);
|
xv_destroy(scope->args);
|
||||||
xv_destroy(locals);
|
xv_destroy(scope->locals);
|
||||||
|
xv_destroy(scope->captures);
|
||||||
|
pic_free(pic, scope);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -921,8 +918,69 @@ destroy_codegen_state(codegen_state *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_activation(codegen_context *cxt)
|
emit_n(codegen_state *state, enum pic_opcode insn)
|
||||||
{
|
{
|
||||||
|
pic_state *pic = state->pic;
|
||||||
|
codegen_context *cxt = state->cxt;
|
||||||
|
|
||||||
|
if (cxt->clen >= cxt->ccapa) {
|
||||||
|
cxt->ccapa *= 2;
|
||||||
|
cxt->code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->ccapa);
|
||||||
|
}
|
||||||
|
cxt->code[cxt->clen].insn = insn;
|
||||||
|
cxt->clen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_i(codegen_state *state, enum pic_opcode insn, int i)
|
||||||
|
{
|
||||||
|
pic_state *pic = state->pic;
|
||||||
|
codegen_context *cxt = state->cxt;
|
||||||
|
|
||||||
|
if (cxt->clen >= cxt->ccapa) {
|
||||||
|
cxt->ccapa *= 2;
|
||||||
|
cxt->code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->ccapa);
|
||||||
|
}
|
||||||
|
cxt->code[cxt->clen].insn = insn;
|
||||||
|
cxt->code[cxt->clen].u.i = i;
|
||||||
|
cxt->clen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_c(codegen_state *state, enum pic_opcode insn, char c)
|
||||||
|
{
|
||||||
|
pic_state *pic = state->pic;
|
||||||
|
codegen_context *cxt = state->cxt;
|
||||||
|
|
||||||
|
if (cxt->clen >= cxt->ccapa) {
|
||||||
|
cxt->ccapa *= 2;
|
||||||
|
cxt->code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->ccapa);
|
||||||
|
}
|
||||||
|
cxt->code[cxt->clen].insn = insn;
|
||||||
|
cxt->code[cxt->clen].u.c = c;
|
||||||
|
cxt->clen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_r(codegen_state *state, enum pic_opcode insn, int d, int i)
|
||||||
|
{
|
||||||
|
pic_state *pic = state->pic;
|
||||||
|
codegen_context *cxt = state->cxt;
|
||||||
|
|
||||||
|
if (cxt->clen >= cxt->ccapa) {
|
||||||
|
cxt->ccapa *= 2;
|
||||||
|
cxt->code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->ccapa);
|
||||||
|
}
|
||||||
|
cxt->code[cxt->clen].insn = insn;
|
||||||
|
cxt->code[cxt->clen].u.r.depth = d;
|
||||||
|
cxt->code[cxt->clen].u.r.idx = i;
|
||||||
|
cxt->clen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_activation(codegen_state *state)
|
||||||
|
{
|
||||||
|
codegen_context *cxt = state->cxt;
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
xhash regs;
|
xhash regs;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
@ -944,13 +1002,10 @@ create_activation(codegen_context *cxt)
|
||||||
n = xh_val(xh_get_ptr(®s, xv_A(cxt->captures, i)), size_t);
|
n = xh_val(xh_get_ptr(®s, xv_A(cxt->captures, i)), size_t);
|
||||||
if (n <= xv_size(cxt->args) || (cxt->varg && n == xv_size(cxt->args) + 1)) {
|
if (n <= xv_size(cxt->args) || (cxt->varg && n == xv_size(cxt->args) + 1)) {
|
||||||
/* copy arguments to capture variable area */
|
/* copy arguments to capture variable area */
|
||||||
cxt->code[cxt->clen].insn = OP_LREF;
|
emit_i(state, OP_LREF, (int)n);
|
||||||
cxt->code[cxt->clen].u.i = (int)n;
|
|
||||||
cxt->clen++;
|
|
||||||
} else {
|
} else {
|
||||||
/* otherwise, just extend the stack */
|
/* otherwise, just extend the stack */
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
emit_n(state, OP_PUSHNONE);
|
||||||
cxt->clen++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,7 +1060,7 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
||||||
|
|
||||||
state->cxt = cxt;
|
state->cxt = cxt;
|
||||||
|
|
||||||
create_activation(cxt);
|
create_activation(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pic_irep *
|
static struct pic_irep *
|
||||||
|
@ -1111,9 +1166,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
sym = pic_sym_ptr(pic_car(pic, obj));
|
sym = pic_sym_ptr(pic_car(pic, obj));
|
||||||
if (sym == pic->sGREF) {
|
if (sym == pic->sGREF) {
|
||||||
cxt->code[cxt->clen].insn = OP_GREF;
|
emit_i(state, OP_GREF, index_symbol(state, pic_sym_ptr(pic_list_ref(pic, obj, 1))));
|
||||||
cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym_ptr(pic_list_ref(pic, obj, 1)));
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
} else if (sym == pic->sCREF) {
|
} else if (sym == pic->sCREF) {
|
||||||
pic_sym *name;
|
pic_sym *name;
|
||||||
|
@ -1121,10 +1174,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
depth = pic_int(pic_list_ref(pic, obj, 1));
|
depth = pic_int(pic_list_ref(pic, obj, 1));
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, obj, 2));
|
name = pic_sym_ptr(pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_CREF;
|
emit_r(state, OP_CREF, depth, index_capture(state, name, depth));
|
||||||
cxt->code[cxt->clen].u.r.depth = depth;
|
|
||||||
cxt->code[cxt->clen].u.r.idx = index_capture(state, name, depth);
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
} else if (sym == pic->sLREF) {
|
} else if (sym == pic->sLREF) {
|
||||||
pic_sym *name;
|
pic_sym *name;
|
||||||
|
@ -1132,14 +1182,10 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
cxt->code[cxt->clen].insn = OP_LREF;
|
emit_i(state, OP_LREF, i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1);
|
||||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cxt->code[cxt->clen].insn = OP_LREF;
|
emit_i(state, OP_LREF, index_local(state, name));
|
||||||
cxt->code[cxt->clen].u.i = index_local(state, name);
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
} else if (sym == pic->sSETBANG) {
|
} else if (sym == pic->sSETBANG) {
|
||||||
pic_value var, val;
|
pic_value var, val;
|
||||||
|
@ -1151,11 +1197,8 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
var = pic_list_ref(pic, obj, 1);
|
var = pic_list_ref(pic, obj, 1);
|
||||||
type = pic_sym_ptr(pic_list_ref(pic, var, 0));
|
type = pic_sym_ptr(pic_list_ref(pic, var, 0));
|
||||||
if (type == pic->sGREF) {
|
if (type == pic->sGREF) {
|
||||||
cxt->code[cxt->clen].insn = OP_GSET;
|
emit_i(state, OP_GSET, index_symbol(state, pic_sym_ptr(pic_list_ref(pic, var, 1))));
|
||||||
cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym_ptr(pic_list_ref(pic, var, 1)));
|
emit_n(state, OP_PUSHNONE);
|
||||||
cxt->clen++;
|
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (type == pic->sCREF) {
|
else if (type == pic->sCREF) {
|
||||||
|
@ -1164,12 +1207,8 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
depth = pic_int(pic_list_ref(pic, var, 1));
|
depth = pic_int(pic_list_ref(pic, var, 1));
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, var, 2));
|
name = pic_sym_ptr(pic_list_ref(pic, var, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_CSET;
|
emit_r(state, OP_CSET, depth, index_capture(state, name, depth));
|
||||||
cxt->code[cxt->clen].u.r.depth = depth;
|
emit_n(state, OP_PUSHNONE);
|
||||||
cxt->code[cxt->clen].u.r.idx = index_capture(state, name, depth);
|
|
||||||
cxt->clen++;
|
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (type == pic->sLREF) {
|
else if (type == pic->sLREF) {
|
||||||
|
@ -1178,18 +1217,12 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
cxt->code[cxt->clen].insn = OP_LSET;
|
emit_i(state, OP_LSET, i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1);
|
||||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1;
|
emit_n(state, OP_PUSHNONE);
|
||||||
cxt->clen++;
|
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cxt->code[cxt->clen].insn = OP_LSET;
|
emit_i(state, OP_LSET, index_local(state, name));
|
||||||
cxt->code[cxt->clen].u.i = index_local(state, name);
|
emit_n(state, OP_PUSHNONE);
|
||||||
cxt->clen++;
|
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1201,9 +1234,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
cxt->irep = pic_realloc(pic, cxt->irep, sizeof(struct pic_irep *) * cxt->icapa);
|
cxt->irep = pic_realloc(pic, cxt->irep, sizeof(struct pic_irep *) * cxt->icapa);
|
||||||
}
|
}
|
||||||
k = (int)cxt->ilen++;
|
k = (int)cxt->ilen++;
|
||||||
cxt->code[cxt->clen].insn = OP_LAMBDA;
|
emit_i(state, OP_LAMBDA, k);
|
||||||
cxt->code[cxt->clen].u.i = k;
|
|
||||||
cxt->clen++;
|
|
||||||
|
|
||||||
cxt->irep[k] = codegen_lambda(state, obj);
|
cxt->irep[k] = codegen_lambda(state, obj);
|
||||||
return;
|
return;
|
||||||
|
@ -1213,13 +1244,16 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
|
|
||||||
cxt->code[cxt->clen].insn = OP_JMPIF;
|
s = (int)cxt->clen;
|
||||||
s = (int)cxt->clen++;
|
|
||||||
|
emit_n(state, OP_JMPIF);
|
||||||
|
|
||||||
/* if false branch */
|
/* if false branch */
|
||||||
codegen(state, pic_list_ref(pic, obj, 3));
|
codegen(state, pic_list_ref(pic, obj, 3));
|
||||||
cxt->code[cxt->clen].insn = OP_JMP;
|
|
||||||
t = (int)cxt->clen++;
|
t = (int)cxt->clen;
|
||||||
|
|
||||||
|
emit_n(state, OP_JMP);
|
||||||
|
|
||||||
cxt->code[s].u.i = (int)cxt->clen - s;
|
cxt->code[s].u.i = (int)cxt->clen - s;
|
||||||
|
|
||||||
|
@ -1234,8 +1268,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
||||||
if (i++ != 0) {
|
if (i++ != 0) {
|
||||||
cxt->code[cxt->clen].insn = OP_POP;
|
emit_n(state, OP_POP);
|
||||||
cxt->clen++;
|
|
||||||
}
|
}
|
||||||
codegen(state, elt);
|
codegen(state, elt);
|
||||||
}
|
}
|
||||||
|
@ -1247,26 +1280,16 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
obj = pic_list_ref(pic, obj, 1);
|
obj = pic_list_ref(pic, obj, 1);
|
||||||
switch (pic_type(obj)) {
|
switch (pic_type(obj)) {
|
||||||
case PIC_TT_BOOL:
|
case PIC_TT_BOOL:
|
||||||
if (pic_true_p(obj)) {
|
emit_n(state, (pic_true_p(obj) ? OP_PUSHTRUE : OP_PUSHFALSE));
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHTRUE;
|
|
||||||
} else {
|
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHFALSE;
|
|
||||||
}
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
case PIC_TT_INT:
|
case PIC_TT_INT:
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHINT;
|
emit_i(state, OP_PUSHINT, pic_int(obj));
|
||||||
cxt->code[cxt->clen].u.i = pic_int(obj);
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
case PIC_TT_NIL:
|
case PIC_TT_NIL:
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNIL;
|
emit_n(state, OP_PUSHNIL);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
case PIC_TT_CHAR:
|
case PIC_TT_CHAR:
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHCHAR;
|
emit_c(state, OP_PUSHCHAR, pic_char(obj));
|
||||||
cxt->code[cxt->clen].u.c = pic_char(obj);
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
if (cxt->plen >= cxt->pcapa) {
|
if (cxt->plen >= cxt->pcapa) {
|
||||||
|
@ -1275,122 +1298,103 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
}
|
}
|
||||||
pidx = (int)cxt->plen++;
|
pidx = (int)cxt->plen++;
|
||||||
cxt->pool[pidx] = obj;
|
cxt->pool[pidx] = obj;
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHCONST;
|
emit_i(state, OP_PUSHCONST, pidx);
|
||||||
cxt->code[cxt->clen].u.i = pidx;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sym == pic->sCONS) {
|
else if (sym == pic->sCONS) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_CONS;
|
emit_n(state, OP_CONS);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sCAR) {
|
else if (sym == pic->sCAR) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_CAR;
|
emit_n(state, OP_CAR);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sCDR) {
|
else if (sym == pic->sCDR) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_CDR;
|
emit_n(state, OP_CDR);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sNILP) {
|
else if (sym == pic->sNILP) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_NILP;
|
emit_n(state, OP_NILP);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sSYMBOLP) {
|
else if (sym == pic->sSYMBOLP) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_SYMBOLP;
|
emit_n(state, OP_SYMBOLP);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sPAIRP) {
|
else if (sym == pic->sPAIRP) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_PAIRP;
|
emit_n(state, OP_PAIRP);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sADD) {
|
else if (sym == pic->sADD) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_ADD;
|
emit_n(state, OP_ADD);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sSUB) {
|
else if (sym == pic->sSUB) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_SUB;
|
emit_n(state, OP_SUB);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sMUL) {
|
else if (sym == pic->sMUL) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_MUL;
|
emit_n(state, OP_MUL);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sDIV) {
|
else if (sym == pic->sDIV) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_DIV;
|
emit_n(state, OP_DIV);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sMINUS) {
|
else if (sym == pic->sMINUS) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_MINUS;
|
emit_n(state, OP_MINUS);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sEQ) {
|
else if (sym == pic->sEQ) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_EQ;
|
emit_n(state, OP_EQ);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sLT) {
|
else if (sym == pic->sLT) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_LT;
|
emit_n(state, OP_LT);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sLE) {
|
else if (sym == pic->sLE) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
cxt->code[cxt->clen].insn = OP_LE;
|
emit_n(state, OP_LE);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sGT) {
|
else if (sym == pic->sGT) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_LT;
|
emit_n(state, OP_LT);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sGE) {
|
else if (sym == pic->sGE) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_LE;
|
emit_n(state, OP_LE);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sNOT) {
|
else if (sym == pic->sNOT) {
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
cxt->code[cxt->clen].insn = OP_NOT;
|
emit_n(state, OP_NOT);
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sCALL || sym == pic->sTAILCALL) {
|
else if (sym == pic->sCALL || sym == pic->sTAILCALL) {
|
||||||
|
@ -1400,9 +1404,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
||||||
codegen(state, elt);
|
codegen(state, elt);
|
||||||
}
|
}
|
||||||
cxt->code[cxt->clen].insn = (sym == pic->sCALL) ? OP_CALL : OP_TAILCALL;
|
emit_i(state, (sym == pic->sCALL ? OP_CALL : OP_TAILCALL), len - 1);
|
||||||
cxt->code[cxt->clen].u.i = len - 1;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sCALL_WITH_VALUES || sym == pic->sTAILCALL_WITH_VALUES) {
|
else if (sym == pic->sCALL_WITH_VALUES || sym == pic->sTAILCALL_WITH_VALUES) {
|
||||||
|
@ -1410,13 +1412,9 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
codegen(state, pic_list_ref(pic, obj, 2));
|
codegen(state, pic_list_ref(pic, obj, 2));
|
||||||
codegen(state, pic_list_ref(pic, obj, 1));
|
codegen(state, pic_list_ref(pic, obj, 1));
|
||||||
/* call producer */
|
/* call producer */
|
||||||
cxt->code[cxt->clen].insn = OP_CALL;
|
emit_i(state, OP_CALL, 1);
|
||||||
cxt->code[cxt->clen].u.i = 1;
|
|
||||||
cxt->clen++;
|
|
||||||
/* call consumer */
|
/* call consumer */
|
||||||
cxt->code[cxt->clen].insn = (sym == pic->sCALL_WITH_VALUES) ? OP_CALL : OP_TAILCALL;
|
emit_i(state, (sym == pic->sCALL_WITH_VALUES ? OP_CALL : OP_TAILCALL), -1);
|
||||||
cxt->code[cxt->clen].u.i = -1;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sym == pic->sRETURN) {
|
else if (sym == pic->sRETURN) {
|
||||||
|
@ -1426,9 +1424,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
pic_for_each (elt, pic_cdr(pic, obj), it) {
|
||||||
codegen(state, elt);
|
codegen(state, elt);
|
||||||
}
|
}
|
||||||
cxt->code[cxt->clen].insn = OP_RET;
|
emit_i(state, OP_RET, len - 1);
|
||||||
cxt->code[cxt->clen].u.i = len - 1;
|
|
||||||
cxt->clen++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pic_errorf(pic, "codegen: unknown AST type ~s", obj);
|
pic_errorf(pic, "codegen: unknown AST type ~s", obj);
|
||||||
|
|
Loading…
Reference in New Issue