vua: Improve bcstack windowing
authorJack Miller <jack@codezen.org>
Sun, 18 Sep 2016 02:43:27 +0000 (21:43 -0500)
committerJack Miller <jack@codezen.org>
Sun, 18 Sep 2016 02:43:27 +0000 (21:43 -0500)
This is not only better memory use, but also properly separates the
bytecode of nested function declarations which is more correct and
simplifies dumping the resulting prototypes.

vua/vua_bc.c
vua/vua_bc_dump.c
vua/vua_obj.h
vua/vua_parse.c

index 86f176c..c10447e 100644 (file)
@@ -131,21 +131,19 @@ static void __expr_free2(parser_state_t *parser, expr_t *expr, expr_t *expr2)
 static BCPos __emit(parser_state_t *parser, BCIns ins)
 {
     BCInsLine *new;
-    BCPos pc = parser->func->pc;
-    ptrdiff_t delta = parser->func->bcbase - parser->bcstack;
-    ptrdiff_t end = &parser->func->bcbase[pc] - &parser->bcstack[parser->bclim];
+    func_t *func = parser->func;
+    BCPos pc = func->pc;
+    ptrdiff_t delta = func->bcbase - parser->bcstack;
+    int rem = func->max_pc - func->pc;
 
     /* Resolve pending jumps */
 
-    __jmp_patchval(parser, parser->func->jpc, pc, NO_REG, pc);
-    parser->func->jpc = NO_JMP;
+    __jmp_patchval(parser, func->jpc, pc, NO_REG, pc);
+    func->jpc = NO_JMP;
 
-    if (end >= 0) {
+    if (rem == 0) {
         new = objcache_get(&bc_cache, (parser->bclim + BC_STRIDE) * sizeof(BCInsLine));
-        if (!new) {
-            printk("Failed to allocate bytecode space\n");
-            return (BCPos) -1;
-        }
+        assert(new);
 
         if (parser->bcstack) {
             memcpy(new, parser->bcstack, parser->bclim * sizeof(BCInsLine));
@@ -155,12 +153,13 @@ static BCPos __emit(parser_state_t *parser, BCIns ins)
         parser->bcstack = new;
         parser->bclim += BC_STRIDE;
 
-        parser->func->bcbase = new + delta;
+        func->bcbase = new + delta;
+        func->max_pc += BC_STRIDE;
     }
 
-    parser->func->bcbase[pc].ins = ins;
-    parser->func->bcbase[pc].line = parser->lexer.line;
-    parser->func->pc++;
+    func->bcbase[pc].ins = ins;
+    func->bcbase[pc].line = parser->lexer.line;
+    func->pc++;
 
     return pc;
 }
index fe5314f..e0d2c87 100644 (file)
@@ -42,39 +42,22 @@ static void __print_hint(vua_proto_t *proto, s32 part, BCMode mode)
     }
 }
 
-static void __bc_dump(vua_proto_t *proto, int offset, int pc_off)
+void vua_bc_dump(vua_proto_t *proto)
 {
     BCIns *bc = (BCIns *) (((u64) proto) + sizeof(vua_proto_t));
     int i, op, a, b, c, d;
-    int sub_func = 0;
-    int sub_po = 0;
 
-    for (i = offset; i < proto->size_bc; i++) {
+    for (i = 0; i < proto->size_bc; i++) {
         op = bc_op(bc[i]);
 
-        if ((op == BC_FUNCF)||(op == BC_FUNCV)) {
-            sub_func++;
-            if (sub_func == 1) {
-                sub_po = i;
-                printk("\n");
-                goto print_ins;
-            }
-        } else if (op == BC_FNEW) {
-            if (sub_func)
-                sub_func--;
-
-            if (sub_func == 0) {
-                d = ~bc_d(bc[i]);
-                __bc_dump(tv_proto(proto->k[d]), 1, sub_po);
-                printk("\n");
-            }
+        if (op == BC_FNEW) {
+            printk("\n");
+            d = ~bc_d(bc[i]);
+            vua_bc_dump(tv_proto(proto->k[d]));
+            printk("\n");
         }
 
-        if (sub_func)
-            continue;
-
-print_ins:
-        printk("%3d : %s\t", (i + pc_off), bc_names[op]);
+        printk("%3d : %s\t", i, bc_names[op]);
 
         a = bc_a(bc[i]);
         printk("%d\t", a);
@@ -98,8 +81,3 @@ print_ins:
         printk("\n");
     }
 }
-
-void vua_bc_dump(vua_proto_t *proto)
-{
-    __bc_dump(proto, 0, 0);
-}
index 77390c4..6185396 100644 (file)
@@ -265,6 +265,7 @@ typedef struct vua_func {
     u8 framesize;       // Stack frame size
 
     BCInsLine *bcbase;  // Bytecode holster
+    BCPos max_pc;       // Size of bcbase window
     BCPos pc;           // Next bytecode position
 
     BCPos jpc;          // Pending jump list
index ef92cf6..889e940 100644 (file)
@@ -926,6 +926,8 @@ static int __parse_body(parser_state_t *parser, expr_t *expr, int needself)
     __new_scope(parser, 0);
 
     child->bcbase = &parent->bcbase[parent->pc];
+    child->max_pc = parent->max_pc - parent->pc;
+
     child->params = __parse_params(parser, needself);
 
     /* Emit opening FUNCV as a place holder */
@@ -933,12 +935,12 @@ static int __parse_body(parser_state_t *parser, expr_t *expr, int needself)
 
     __parse_chunk(parser);
 
-    /* Get prototype and destroy func_t in the process */
+    /* Get prototype and destroy child func_t in the process */
     proto = __prototype(parser);
 
     /* Re-ref in case parsing chunk realloc'd the parser bcstack */
     parent->bcbase = parser->bcstack + oldbase;
-    parent->pc += child->pc;
+    parent->max_pc = parser->bclim - (oldbase / sizeof(BCInsLine));
 
     __expr_init(expr, VRELOCABLE);
     expr->v.r.info = vua_bc_emit_proto(parser, proto);
@@ -986,6 +988,9 @@ int vua_parse(u8 *input_data, u64 len)
 
     __new_scope(state, 0);
 
+    /* Placeholder FUNCV */
+    vua_bc_emit_func(state);
+
     __parse_chunk(state);
 
     proto = __prototype(state);