- int a = boolify(ctx, ra);
- int b = boolify(ctx, rb);
- int result;
- if(op == OP_AND) result = a && b ? 1 : 0;
- else result = a || b ? 1 : 0;
- return naNum(result);
+ naRef *args, func, code, obj = naNil();
+ struct Frame* f;
+ int opf = ctx->opTop - nargs;
+
+ args = &ctx->opStack[opf];
+ func = ctx->opStack[--opf];
+ if(!IS_FUNC(func)) ERR(ctx, "function/method call on uncallable object");
+ code = PTR(func).func->code;
+ if(mcall) obj = ctx->opStack[--opf];
+ ctx->opFrame = opf;
+
+ if(IS_CCODE(code)) {
+ naRef result = (*PTR(code).ccode->fptr)(ctx, obj, nargs, args);
+ if(named) ERR(ctx, "native functions have no named arguments");
+ ctx->opTop = ctx->opFrame;
+ PUSH(result);
+ return &(ctx->fStack[ctx->fTop-1]);
+ }
+
+ if(ctx->fTop >= MAX_RECURSION) ERR(ctx, "call stack overflow");
+
+ f = &(ctx->fStack[ctx->fTop]);
+ f->locals = named ? args[0] : naNewHash(ctx);
+ f->func = func;
+ f->ip = 0;
+ f->bp = ctx->opFrame;
+
+ if(mcall) naHash_set(f->locals, globals->meRef, obj);
+
+ if(named) checkNamedArgs(ctx, PTR(code).code, PTR(f->locals).hash);
+ else setupArgs(ctx, f, args, nargs);
+
+ ctx->fTop++;
+ ctx->opTop = f->bp; /* Pop the stack last, to avoid GC lossage */
+ return f;