From 125e2785025ed1a4363800d712bdf4e782a94cd4 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 20:45:55 +0000 Subject: [PATCH] Clean up calls to C functions, unify opcodes --- builtin.c | 36 ++++++++++++++++++------------------ bytecode.c | 4 ++-- bytecode.h | 2 +- compile.c | 32 +++++++++++++++----------------- execute.c | 40 ++++++++++++---------------------------- opcode_list.h | 6 ++---- 6 files changed, 50 insertions(+), 70 deletions(-) diff --git a/builtin.c b/builtin.c index eea85ed..ae4df33 100644 --- a/builtin.c +++ b/builtin.c @@ -238,24 +238,24 @@ static void f_type(jv input[], jv output[]) { } static struct cfunction function_list[] = { - {f_plus, "_plus", CALL_BUILTIN_3_1}, - {f_minus, "_minus", CALL_BUILTIN_3_1}, - {f_multiply, "_multiply", CALL_BUILTIN_3_1}, - {f_divide, "_divide", CALL_BUILTIN_3_1}, - {f_tonumber, "tonumber", CALL_BUILTIN_1_1}, - {f_tostring, "tostring", CALL_BUILTIN_1_1}, - {f_keys, "keys", CALL_BUILTIN_1_1}, - {f_equal, "_equal", CALL_BUILTIN_3_1}, - {f_notequal, "_notequal", CALL_BUILTIN_3_1}, - {f_less, "_less", CALL_BUILTIN_3_1}, - {f_greater, "_greater", CALL_BUILTIN_3_1}, - {f_lesseq, "_lesseq", CALL_BUILTIN_3_1}, - {f_greatereq, "_greatereq", CALL_BUILTIN_3_1}, - {f_contains, "_contains", CALL_BUILTIN_3_1}, - {f_length, "length", CALL_BUILTIN_1_1}, - {f_type, "type", CALL_BUILTIN_1_1}, - {f_add, "add", CALL_BUILTIN_1_1}, - {f_sort, "sort", CALL_BUILTIN_1_1}, + {f_plus, "_plus", 3}, + {f_minus, "_minus", 3}, + {f_multiply, "_multiply", 3}, + {f_divide, "_divide", 3}, + {f_tonumber, "tonumber", 1}, + {f_tostring, "tostring", 1}, + {f_keys, "keys", 1}, + {f_equal, "_equal", 3}, + {f_notequal, "_notequal", 3}, + {f_less, "_less", 3}, + {f_greater, "_greater", 3}, + {f_lesseq, "_lesseq", 3}, + {f_greatereq, "_greatereq", 3}, + {f_contains, "_contains", 3}, + {f_length, "length", 1}, + {f_type, "type", 1}, + {f_add, "add", 1}, + {f_sort, "sort", 1}, }; static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; diff --git a/bytecode.c b/bytecode.c index bafd047..a18f0d9 100644 --- a/bytecode.c +++ b/bytecode.c @@ -7,7 +7,7 @@ static int bytecode_operation_length(uint16_t* codeptr) { if (opcode_describe(*codeptr)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - return 2 + codeptr[1] * 2; + return 4 + codeptr[1] * 2; } else { return opcode_length(*codeptr); } @@ -42,7 +42,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { if (op->length > 1) { uint16_t imm = bc->code[pc++]; if (op->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - for (int i=0; icode[pc++]; uint16_t idx = bc->code[pc++]; if (idx & ARG_NEWCLOSURE) { diff --git a/bytecode.h b/bytecode.h index 5ffe80a..011745c 100644 --- a/bytecode.h +++ b/bytecode.h @@ -10,7 +10,7 @@ typedef void (*cfunction_ptr)(jv input[], jv output[]); struct cfunction { cfunction_ptr fptr; const char* name; - opcode callop; + int nargs; }; #define MAX_CFUNCTION_ARGS 10 diff --git a/compile.c b/compile.c index c85ef93..d31e0c3 100644 --- a/compile.c +++ b/compile.c @@ -282,7 +282,7 @@ block gen_lambda(block body) { } block gen_call(const char* name, block args) { - inst* i = inst_new(CALL_1_1); + inst* i = inst_new(CALL_JQ); i->arglist = BLOCK(gen_op_block_unbound(CLOSURE_REF, name), args); return BLOCK(inst_block(i), inst_block(inst_new(CALLSEQ_END))); } @@ -439,7 +439,7 @@ static block expand_call_arglist(block b) { block ret = gen_noop(); for (inst* curr; (curr = block_take(&b));) { if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_1_1); + assert(curr->op == CALL_JQ); inst* seq_end = block_take(&b); assert(seq_end && seq_end->op == CALLSEQ_END); // We expand the argument list as a series of instructions @@ -473,7 +473,8 @@ static block expand_call_arglist(block b) { } assert(!arglist.first); - curr->imm.intval = nargs; + assert(nargs > 0); + curr->imm.intval = nargs - 1; ret = BLOCK(ret, prelude, inst_block(curr), callargs, inst_block(seq_end)); break; } @@ -482,7 +483,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 = 2; + int nargs = 1; for (inst* i; (i = block_take(&arglist)); ) { assert(i->op == CLOSURE_CREATE); // FIXME block body = i->subfn; @@ -491,8 +492,8 @@ static block expand_call_arglist(block b) { prelude = BLOCK(prelude, gen_subexp(expand_call_arglist(body))); nargs++; } - assert(curr->op == CALL_1_1); - curr->op = CALL_BUILTIN_1_1; + assert(curr->op == CALL_JQ); + curr->op = CALL_BUILTIN; curr->imm.intval = nargs; assert(!curr->arglist.first); curr->arglist = inst_block(cfunction_ref); @@ -579,26 +580,23 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { const struct opcode_description* op = opcode_describe(curr->op); if (op->length == 0) continue; - uint16_t* opcode_rewrite = &code[pos]; code[pos++] = curr->op; int opflags = op->flags; assert(!(op->flags & OP_IS_CALL_PSEUDO)); - if (curr->op == CALL_BUILTIN_1_1) { + if (curr->op == CALL_BUILTIN) { 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; + //*opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop; code[pos++] = cfunc->bound_by->imm.intval; // FIXME arg errors - assert(nargs > 0); + assert(nargs == bc->globals->cfunctions[cfunc->bound_by->imm.intval].nargs); } else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_1_1); + assert(curr->op == CALL_JQ); int nargs = curr->imm.intval; - assert(nargs > 0 && nargs < 100); //FIXME + assert(nargs >= 0 && nargs < 100); //FIXME code[pos++] = (uint16_t)nargs; curr = curr->next; assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); @@ -609,13 +607,13 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { 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); + assert(nargs == i->compiled->subfunctions[i->imm.intval]->nclosures); } else { code[pos++] = curr->bound_by->imm.intval; // FIXME arg errors - assert(nargs == 1); + assert(nargs == 0); } - for (int i=1; inext; assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); assert(curr->op == CLOSURE_REF); diff --git a/execute.c b/execute.c index 74221a5..8aeee77 100644 --- a/execute.c +++ b/execute.c @@ -167,7 +167,9 @@ jv jq_next() { printf("\t"); const struct opcode_description* opdesc = opcode_describe(opcode); data_stk_elem* param; - for (int i=0; istack_in; i++) { + int stack_in = opdesc->stack_in; + if (stack_in == -1) stack_in = pc[1]; + for (int i=0; iglobals->cfunctions[*pc++]; - func->fptr(cfunc_input, cfunc_output); - top.value = cfunc_output[0]; - if (jv_is_valid(top.value)) { - stack_push(top); - } else { - print_error(top.value); - goto do_backtrack; + for (int i = 1; i < nargs; i++) { + cfunc_input[i] = stack_pop().value; } - break; - } - - case CALL_BUILTIN_3_1: { - assert(*pc == 4); // no closure args allowed - pc++; // skip nclosures - stackval top = stack_pop(); - jv a = stack_pop().value; - jv b = stack_pop().value; - cfunc_input[0] = top.value; - cfunc_input[1] = a; - cfunc_input[2] = b; struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; func->fptr(cfunc_input, cfunc_output); top.value = cfunc_output[0]; @@ -448,15 +431,16 @@ jv jq_next() { break; } - case CALL_1_1: { + case CALL_JQ: { uint16_t nclosures = *pc++; + uint16_t* retaddr = pc + 2 + nclosures*2; frame_ptr new_frame = frame_push(&frame_stk, make_closure(&frame_stk, frame_current(&frame_stk), pc), - pc + nclosures * 2); + retaddr); pc += 2; frame_ptr old_frame = forkable_stack_peek_next(&frame_stk, new_frame); - assert(nclosures - 1 == frame_self(new_frame)->bc->nclosures); - for (int i=0; ibc->nclosures); + for (int i=0; i