Remove the OP_NEWARGS "optimization" (it wasn't).
for(i=0; i<MAX_RECURSION; i++)
c->fStack[i].args = naNil();
- c->argPool = naNewVector(c);
-
// Note we can't use naNewVector() for this; it requires that
// temps exist first.
c->temps = naObj(T_VEC, naGC_get(&(c->pools[T_VEC])));
for(i=0; i < c->opTop; i++)
naGC_mark(c->opStack[i]);
- naGC_mark(c->argPool);
naGC_mark(c->temps);
naGC_mark(c->save);
ctx->opTop = f->bp; // restore the correct stack frame!
ctx->fTop--;
ctx->fStack[ctx->fTop].args.ref.ptr.vec->size = 0;
- naVec_append(ctx->argPool, ctx->fStack[ctx->fTop].args);
PUSH(ctx, a);
break;
case OP_LINE:
case OP_BREAK: // restore stack state (FOLLOW WITH JMP!)
ctx->opTop = ctx->markStack[--ctx->markTop];
break;
- case OP_NEWARGS: // push a new function arg vector
- PUSH(ctx, (naVec_size(ctx->argPool) ?
- naVec_removelast(ctx->argPool) : naNewVector(ctx)));
- break;
default:
ERR(ctx, "BUG: bad opcode");
}
OP_PUSHCONST, OP_PUSHONE, OP_PUSHZERO, OP_PUSHNIL, OP_POP,
OP_DUP, OP_XCHG, OP_INSERT, OP_EXTRACT, OP_MEMBER, OP_SETMEMBER,
OP_LOCAL, OP_SETLOCAL, OP_NEWVEC, OP_VAPPEND, OP_NEWHASH, OP_HAPPEND,
- OP_LINE, OP_MARK, OP_UNMARK, OP_BREAK, OP_NEWARGS
+ OP_LINE, OP_MARK, OP_UNMARK, OP_BREAK
};
struct Frame {
int markTop;
int done;
- // Vector of arguments vectors. A LIFO cache, basically, to avoid
- // thrashing the GC just for function call arguments.
- naRef argPool;
-
// Constants
naRef meRef;
naRef argRef;
} else {
genExpr(p, LEFT(t));
}
- emit(p, OP_NEWARGS);
+ emit(p, OP_NEWVEC);
if(RIGHT(t)) genList(p, RIGHT(t));
emit(p, op);
}
struct Token* t;
struct Parser p;
+ // Protect from garbage collection
+ naVec_append(c->temps, srcFile);
+
// Catch parser errors here.
*errLine = 0;
if(setjmp(p.jumpHandle)) {
// Clean up our mess
naParseDestroy(&p);
+ naVec_append(c->temps, codeObj);
return codeObj;
}