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);
PUSH(ctx, evalAndOr(ctx, op, a, b));
break;
case OP_CAT:
- a = stringify(ctx, POP(ctx)); b = stringify(ctx, POP(ctx));
+ // stringify can call the GC, so don't take stuff of the stack!
+ if(ctx->opTop <= 1) ERR(ctx, "BUG: stack underflow");
+ a = stringify(ctx, ctx->opStack[ctx->opTop-1]);
+ b = stringify(ctx, ctx->opStack[ctx->opTop-2]);
c = naStr_concat(naNewString(ctx), b, a);
+ ctx->opTop -= 2;
PUSH(ctx, c);
break;
case OP_NEG:
break;
case OP_MCALL:
c = POP(ctx); b = POP(ctx); a = POP(ctx); // a,b,c = obj, func, args
+ naVec_append(ctx->temps, a);
setupFuncall(ctx, b, c);
naHash_set(ctx->fStack[ctx->fTop-1].locals, ctx->meRef, a);
break;
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");
}
{
// Return early if an error occurred. It will be visible to the
// caller via naGetError().
+ ctx->error = 0;
if(setjmp(ctx->jumpHandle))
return naNil();