Refactor of function call codegen. Separate codegen for C and jq calls.

This commit is contained in:
Stephen Dolan committed 2012-12-02 20:45:06 +00:00
1 parent 9e743d517a
commit 251f221b85
4 files changed
+44 -50

No files matched your search

+40 -44
View File
@@ -56,12 +56,8 @@ static inst* inst_new(opcode op) {
static void inst_free(struct inst* i) {
free(i->symbol);
if (opcode_describe(i->op)->flags & OP_HAS_BLOCK) {
block_free(i->subfn);
}
if (opcode_describe(i->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
block_free(i->arglist);
}
block_free(i->subfn);
block_free(i->arglist);
if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) {
jv_free(i->imm.constant);
}
@@ -486,7 +482,7 @@ static block expand_call_arglist(block b) {
// Arguments to C functions not yet supported
inst* cfunction_ref = block_take(&arglist);
block prelude = gen_noop();
int nargs = 0;
int nargs = 2;
for (inst* i; (i = block_take(&arglist)); ) {
assert(i->op == CLOSURE_CREATE); // FIXME
block body = i->subfn;
@@ -496,8 +492,11 @@ static block expand_call_arglist(block b) {
nargs++;
}
assert(curr->op == CALL_1_1);
curr->imm.intval = 1;
ret = BLOCK(ret, prelude, inst_block(curr), inst_block(cfunction_ref), inst_block(seq_end));
curr->op = CALL_BUILTIN_1_1;
curr->imm.intval = nargs;
assert(!curr->arglist.first);
curr->arglist = inst_block(cfunction_ref);
ret = BLOCK(ret, prelude, inst_block(curr), inst_block(seq_end));
break;
}
}
@@ -584,38 +583,46 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
code[pos++] = curr->op;
int opflags = op->flags;
assert(!(op->flags & OP_IS_CALL_PSEUDO));
if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
if (curr->op == CALL_BUILTIN_1_1) {
int nargs = curr->imm.intval;
code[pos++] = (uint16_t)nargs;
assert(block_is_single(curr->arglist));
inst* cfunc = curr->arglist.first;
assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C);
assert(opcode_length(*opcode_rewrite) ==
opcode_length(bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop));
*opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop;
code[pos++] = cfunc->bound_by->imm.intval;
// FIXME arg errors
assert(nargs > 0);
} else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
assert(curr->op == CALL_1_1);
int nargs = curr->imm.intval;
assert(nargs > 0 && nargs < 100); //FIXME
code[pos++] = (uint16_t)nargs;
int desired_params = 0;
for (int i=0; i<nargs; i++) {
curr = curr->next;
assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO);
assert(curr->bound_by->op == CLOSURE_CREATE ||
curr->bound_by->op == CLOSURE_PARAM);
code[pos++] = nesting_level(bc, curr->bound_by);
if (curr->bound_by->op == CLOSURE_CREATE) {
code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE;
inst* i = curr->bound_by;
// FIXME arg errors
assert(nargs - 1 == i->compiled->subfunctions[i->imm.intval]->nclosures);
} else {
code[pos++] = curr->bound_by->imm.intval;
// FIXME arg errors
assert(nargs == 1);
}
for (int i=1; i<nargs; i++) {
curr = curr->next;
assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO);
assert(curr->op == CLOSURE_REF);
code[pos++] = nesting_level(bc, curr->bound_by);
switch (curr->bound_by->op) {
default: assert(0 && "Unknown type of argument");
case CLOSURE_CREATE:
code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE;
if (i == 0) {
inst* i = curr->bound_by;
desired_params = i->compiled->subfunctions[i->imm.intval]->nclosures;
}
break;
case CLOSURE_PARAM:
code[pos++] = curr->bound_by->imm.intval;
if (i == 0) desired_params = 0;
break;
case CLOSURE_CREATE_C:
code[pos++] = curr->bound_by->imm.intval;
*opcode_rewrite = bc->globals->cfunctions[curr->bound_by->imm.intval].callop;
if (i == 0) desired_params = 0;
break;
}
assert(curr->bound_by->op == CLOSURE_CREATE);
code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE;
}
assert(nargs - 1 == desired_params);
} else if (opflags & OP_HAS_CONSTANT) {
code[pos++] = jv_array_length(jv_copy(constant_pool));
constant_pool = jv_array_append(constant_pool, jv_copy(curr->imm.constant));
@@ -629,17 +636,6 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
assert(curr->imm.target->bytecode_pos > pos); // only forward branches
code[pos] = curr->imm.target->bytecode_pos - (pos + 1);
pos++;
} else if (opflags & OP_HAS_CFUNC) {
assert(curr->symbol);
int found = 0;
for (int i=0; i<bc->globals->ncfunctions; i++) {
if (!strcmp(curr->symbol, bc->globals->cfunctions[i].name)) {
code[pos++] = i;
found = 1;
break;
}
}
assert(found);
} else if (op->length > 1) {
assert(0 && "codegen not implemented for this operation");
}