Always wrap functions in closures.
This has a couple of pros: - It simplifies some code that used to have to check whether a called thing is a bare function or a closure. - It's faster because we don't need to do the above checks every time something is called. - It lets us more precisely type some fields that used to be Obj* because they could hold an ObjClosure* or ObjFn*. The cost is that we allocate a closure every time a function is declared, even if it has no upvalues. Since functions are called way more often than they are declared, this is still a net win. On my Mac laptop: api_call - wren 0.06s 0.0020 104.73% api_foreign_method - wren 0.32s 0.0040 101.89% binary_trees - wren 0.23s 0.0057 98.82% binary_trees_gc - wren 0.79s 0.0170 98.46% delta_blue - wren 0.13s 0.0031 101.36% fib - wren 0.23s 0.0038 103.15% fibers - wren 0.04s 0.0017 98.97% for - wren 0.08s 0.0017 107.81% method_call - wren 0.12s 0.0024 98.60% map_numeric - wren 0.31s 0.0052 103.93% map_string - wren 0.11s 0.0113 97.97% string_equals - wren 0.20s 0.0023 107.75%
This commit is contained in:
@@ -12,17 +12,24 @@ void metaCompile(WrenVM* vm)
|
||||
// Evaluate the code in the module where the calling function was defined.
|
||||
// That's one stack frame back from the top since the top-most frame is the
|
||||
// helper eval() method in Meta itself.
|
||||
Value callingFn = OBJ_VAL(vm->fiber->frames[vm->fiber->numFrames - 2].fn);
|
||||
ObjModule* module = IS_FN(callingFn)
|
||||
? AS_FN(callingFn)->module
|
||||
: AS_CLOSURE(callingFn)->fn->module;
|
||||
ObjClosure* caller = vm->fiber->frames[vm->fiber->numFrames - 2].closure;
|
||||
ObjModule* module = caller->fn->module;
|
||||
|
||||
// Compile it.
|
||||
ObjFn* fn = wrenCompile(vm, module, wrenGetSlotString(vm, 1), false);
|
||||
|
||||
// Return the result. We can't use the public API for this since we have a
|
||||
// bare ObjFn.
|
||||
vm->apiStack[0] = fn != NULL ? OBJ_VAL(fn) : NULL_VAL;
|
||||
if (fn == NULL)
|
||||
{
|
||||
vm->apiStack[0] = NULL_VAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
wrenPushRoot(vm, (Obj*)fn);
|
||||
vm->apiStack[0] = OBJ_VAL(wrenNewClosure(vm, fn));
|
||||
wrenPopRoot(vm);
|
||||
}
|
||||
}
|
||||
|
||||
const char* wrenMetaSource()
|
||||
|
||||
Reference in New Issue
Block a user