]> granicus.if.org Git - jq/commitdiff
Clean up calls to C functions, unify opcodes
authorStephen Dolan <mu@netsoc.tcd.ie>
Sun, 2 Dec 2012 20:45:55 +0000 (20:45 +0000)
committerStephen Dolan <mu@netsoc.tcd.ie>
Sun, 2 Dec 2012 20:45:55 +0000 (20:45 +0000)
builtin.c
bytecode.c
bytecode.h
compile.c
execute.c
opcode_list.h

index eea85ed62e767670556da7501c5faa8c6f851fb1..ae4df33b1afbfef63766db36a7021785252ae651 100644 (file)
--- 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])};
index bafd047495e071b01d7f2f4c2ba1c1f0b5fecbbc..a18f0d90ea6a5b92298674e0cba2cecc4fe7ed64 100644 (file)
@@ -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; i<imm; i++) {
+      for (int i=0; i<imm+1; i++) {
         uint16_t level = bc->code[pc++];
         uint16_t idx = bc->code[pc++];
         if (idx & ARG_NEWCLOSURE) {
index 5ffe80a63b8e9a531cda8b55fb0e4c850fa4af5c..011745c0d7b0953e3693b867c5ef91411ab7ba1e 100644 (file)
@@ -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
index c85ef9382f215f8a7285ac68dad3992c3f70206e..d31e0c346d2d2ba0e06a8a566c190f1aa34d61e1 100644 (file)
--- 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; i<nargs; i++) {
+      for (int i=0; i<nargs; i++) {
         curr = curr->next;
         assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO);
         assert(curr->op == CLOSURE_REF);
index 74221a550485fc97fbf4a9f86e6a42db0e2b9796..8aeee779ec8bfe0b95b50cf9f8e94bd60d9dbcf2 100644 (file)
--- 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; i<opdesc->stack_in; i++) {
+    int stack_in = opdesc->stack_in;
+    if (stack_in == -1) stack_in = pc[1];
+    for (int i=0; i<stack_in; i++) {
       if (i == 0) {
         param = forkable_stack_peek(&data_stk);
       } else {
@@ -410,32 +412,13 @@ jv jq_next() {
       return value;
     }
       
-    case CALL_BUILTIN_1_1: {
-      assert(*pc == 2);
-      pc++; // skip nclosures
+    case CALL_BUILTIN: {
+      int nargs = *pc++;
       stackval top = stack_pop();
       cfunc_input[0] = top.value;
-      struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->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; i<nclosures-1; i++) {
+      assert(nclosures == frame_self(new_frame)->bc->nclosures);
+      for (int i=0; i<nclosures; i++) {
         *frame_closure_arg(new_frame, i) = make_closure(&frame_stk, old_frame, pc);
         pc += 2;
       }
index 34a68e1c927d47bbe4b57e177340551e4a9e7add..27211a2d1adf38ce7e6d501a04677f657b08c726 100644 (file)
@@ -17,11 +17,9 @@ OP(INSERT, NONE,    4, 2)
 
 OP(ASSIGN, VARIABLE, 3, 0)
 
-OP(CALL_BUILTIN_1_1, CFUNC, 1, 1)
-OP(WTFBROKEN, CFUNC, 2, 1)
-OP(CALL_BUILTIN_3_1, CFUNC, 3, 1)
+OP(CALL_BUILTIN, CFUNC, -1, 1)
 
-OP(CALL_1_1, UFUNC, 1, 1)
+OP(CALL_JQ, UFUNC, 1, 1)
 OP(RET, NONE, 1, 1)
 
 OP(CALLSEQ_END, CALLSEQ_END_IMM, 0, 0)