]> granicus.if.org Git - jq/commitdiff
Refactor of function call codegen. Separate codegen for C and jq calls.
authorStephen Dolan <mu@netsoc.tcd.ie>
Sat, 1 Dec 2012 19:41:36 +0000 (19:41 +0000)
committerStephen Dolan <mu@netsoc.tcd.ie>
Sun, 2 Dec 2012 20:45:06 +0000 (20:45 +0000)
compile.c
execute.c
opcode.c
opcode_list.h

index 46e5dd881f0b4e4e1851507526b6dd1dccfe8a49..c85ef9382f215f8a7285ac68dad3992c3f70206e 100644 (file)
--- 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; 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");
     }
index fa6b1b79c70ffd8a5f98d35cf41e8ae96bec0c50..74221a550485fc97fbf4a9f86e6a42db0e2b9796 100644 (file)
--- 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;
index 6e85e7093cd29b335d72ea3c785b540a57a832ad..c4c6356d35891e17cb8f8b7576363d62d23f18b7 100644 (file)
--- 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
index 00817a1387fce8d388c1f104e731f0fc0d98c97d..34a68e1c927d47bbe4b57e177340551e4a9e7add 100644 (file)
@@ -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)