From: Stephen Dolan Date: Sat, 1 Dec 2012 19:41:36 +0000 (+0000) Subject: Refactor of function call codegen. Separate codegen for C and jq calls. X-Git-Tag: jq-1.2~33 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=251f221b85216ca50329c4ef1788fc617863ce06;p=jq Refactor of function call codegen. Separate codegen for C and jq calls. --- diff --git a/compile.c b/compile.c index 46e5dd8..c85ef93 100644 --- a/compile.c +++ b/compile.c @@ -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; inext; + 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; inext; 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; iglobals->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"); } diff --git a/execute.c b/execute.c index fa6b1b7..74221a5 100644 --- a/execute.c +++ b/execute.c @@ -411,9 +411,8 @@ jv jq_next() { } case CALL_BUILTIN_1_1: { - assert(*pc == 1); // no closure args allowed + assert(*pc == 2); pc++; // skip nclosures - pc++; // skip level stackval top = stack_pop(); cfunc_input[0] = top.value; struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; @@ -429,9 +428,8 @@ jv jq_next() { } case CALL_BUILTIN_3_1: { - assert(*pc == 1); // no closure args allowed + assert(*pc == 4); // no closure args allowed pc++; // skip nclosures - pc++; // skip level stackval top = stack_pop(); jv a = stack_pop().value; jv b = stack_pop().value; diff --git a/opcode.c b/opcode.c index 6e85e70..c4c6356 100644 --- a/opcode.c +++ b/opcode.c @@ -5,7 +5,7 @@ #define CONSTANT OP_HAS_CONSTANT, 2 #define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3 #define BRANCH OP_HAS_BRANCH, 2 -#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 +#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC), 3 #define UFUNC (OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 #define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0 #define CLOSURE_PARAM_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 diff --git a/opcode_list.h b/opcode_list.h index 00817a1..34a68e1 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -18,7 +18,7 @@ OP(INSERT, NONE, 4, 2) OP(ASSIGN, VARIABLE, 3, 0) OP(CALL_BUILTIN_1_1, CFUNC, 1, 1) -OP(CALL_BUILTIN_2_1, CFUNC, 2, 1) +OP(WTFBROKEN, CFUNC, 2, 1) OP(CALL_BUILTIN_3_1, CFUNC, 3, 1) OP(CALL_1_1, UFUNC, 1, 1)