mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-09 21:28:39 +01:00
Fn call: move arity check into interpret loop, which avoid the expensive if after the call, since runtime errors originating inside the call itself will still be handled, we only have the one emitted from call itself.
This brings the benchmark back up to where it was.
This commit is contained in:
@ -248,13 +248,6 @@ DEF_PRIMITIVE(fn_arity)
|
||||
|
||||
static void call_fn(WrenVM* vm, Value* args, int numArgs)
|
||||
{
|
||||
// We only care about missing arguments, not extras.
|
||||
if (AS_CLOSURE(args[0])->fn->arity > numArgs)
|
||||
{
|
||||
vm->fiber->error = CONST_STRING(vm, "Function expects more arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
// +1 to include the function itself.
|
||||
wrenCallFunction(vm, vm->fiber, AS_CLOSURE(args[0]), numArgs + 1);
|
||||
}
|
||||
|
||||
@ -774,6 +774,21 @@ static Value getModuleVariable(WrenVM* vm, ObjModule* module,
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
inline static bool checkArity(WrenVM* vm, Value value, int numArgs)
|
||||
{
|
||||
ASSERT(IS_CLOSURE(value), "Receiver must be a closure.");
|
||||
ObjFn* fn = AS_CLOSURE(value)->fn;
|
||||
|
||||
// We only care about missing arguments, not extras. The "- 1" is because
|
||||
// numArgs includes the receiver, the function itself, which we don't want to
|
||||
// count.
|
||||
if (numArgs - 1 >= fn->arity) return true;
|
||||
|
||||
vm->fiber->error = CONST_STRING(vm, "Function expects more arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// The main bytecode interpreter loop. This is where the magic happens. It is
|
||||
// also, as you can imagine, highly performance critical.
|
||||
static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
|
||||
@ -1016,9 +1031,13 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
|
||||
break;
|
||||
|
||||
case METHOD_FUNCTION_CALL:
|
||||
if (!checkArity(vm, args[0], numArgs)) {
|
||||
RUNTIME_ERROR();
|
||||
break;
|
||||
}
|
||||
|
||||
STORE_FRAME();
|
||||
method->as.primitive(vm, args);
|
||||
if (wrenHasError(fiber)) RUNTIME_ERROR();
|
||||
LOAD_FRAME();
|
||||
break;
|
||||
|
||||
|
||||
3
test/core/function/call_runtime_error.wren
Normal file
3
test/core/function/call_runtime_error.wren
Normal file
@ -0,0 +1,3 @@
|
||||
var f1 = Fn.new {|a, b| a + b } // expect runtime error: Bool does not implement '+(_)'.
|
||||
f1.call(true, false)
|
||||
|
||||
Reference in New Issue
Block a user