mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 22:28:45 +01:00
Revamp wrenCall to work with slots.
Now, you call wrenEnsureSlots() and then wrenSetSlot___() to set up the receiver and arguments before the call. Then wrenCall() is passed a handle to the stub function that makes the call. After that, you can get the result using wrenGetSlot___(). This is a little more verbose to use, but it's more flexible, simpler, and much faster in the VM. The call benchmark is 185% of the previous speed.
This commit is contained in:
@ -32,21 +32,32 @@ static void call(WrenVM* vm)
|
||||
|
||||
wrenInterpret(otherVM, testScript);
|
||||
|
||||
WrenValue* method = wrenGetMethod(otherVM, "main", "Test", "method(_,_,_,_)");
|
||||
WrenValue* method = wrenMakeCallHandle(otherVM, "method(_,_,_,_)");
|
||||
|
||||
wrenEnsureSlots(otherVM, 1);
|
||||
wrenGetVariable(otherVM, "main", "Test", 0);
|
||||
WrenValue* testClass = wrenGetSlotValue(otherVM, 0);
|
||||
|
||||
double startTime = (double)clock() / CLOCKS_PER_SEC;
|
||||
|
||||
double result = 0;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
WrenValue* resultValue;
|
||||
wrenCall(otherVM, method, &resultValue, "dddd", 1.0, 2.0, 3.0, 4.0);
|
||||
result += wrenGetValueDouble(otherVM, resultValue);
|
||||
wrenReleaseValue(otherVM, resultValue);
|
||||
wrenEnsureSlots(otherVM, 5);
|
||||
wrenSetSlotValue(otherVM, 0, testClass);
|
||||
wrenSetSlotDouble(otherVM, 1, 1.0);
|
||||
wrenSetSlotDouble(otherVM, 2, 2.0);
|
||||
wrenSetSlotDouble(otherVM, 3, 3.0);
|
||||
wrenSetSlotDouble(otherVM, 4, 4.0);
|
||||
|
||||
wrenCall(otherVM, method);
|
||||
|
||||
result += wrenGetSlotDouble(otherVM, 0);
|
||||
}
|
||||
|
||||
double elapsed = (double)clock() / CLOCKS_PER_SEC - startTime;
|
||||
|
||||
wrenReleaseValue(otherVM, testClass);
|
||||
wrenReleaseValue(otherVM, method);
|
||||
wrenFreeVM(otherVM);
|
||||
|
||||
|
||||
@ -5,33 +5,75 @@
|
||||
|
||||
void callRunTests(WrenVM* vm)
|
||||
{
|
||||
WrenValue* noParams = wrenGetMethod(vm, "main", "Call", "noParams");
|
||||
WrenValue* zero = wrenGetMethod(vm, "main", "Call", "zero()");
|
||||
WrenValue* one = wrenGetMethod(vm, "main", "Call", "one(_)");
|
||||
WrenValue* two = wrenGetMethod(vm, "main", "Call", "two(_,_)");
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "main", "Call", 0);
|
||||
WrenValue* callClass = wrenGetSlotValue(vm, 0);
|
||||
|
||||
WrenValue* noParams = wrenMakeCallHandle(vm, "noParams");
|
||||
WrenValue* zero = wrenMakeCallHandle(vm, "zero()");
|
||||
WrenValue* one = wrenMakeCallHandle(vm, "one(_)");
|
||||
WrenValue* two = wrenMakeCallHandle(vm, "two(_,_)");
|
||||
|
||||
// Different arity.
|
||||
wrenCall(vm, noParams, NULL, "");
|
||||
wrenCall(vm, zero, NULL, "");
|
||||
wrenCall(vm, one, NULL, "i", 1);
|
||||
wrenCall(vm, two, NULL, "ii", 1, 2);
|
||||
|
||||
WrenValue* getValue = wrenGetMethod(vm, "main", "Call", "getValue(_)");
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenCall(vm, noParams);
|
||||
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenCall(vm, zero);
|
||||
|
||||
wrenEnsureSlots(vm, 2);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotDouble(vm, 1, 1.0);
|
||||
wrenCall(vm, one);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotDouble(vm, 1, 1.0);
|
||||
wrenSetSlotDouble(vm, 2, 2.0);
|
||||
wrenCall(vm, two);
|
||||
|
||||
// Returning a value.
|
||||
WrenValue* value = NULL;
|
||||
wrenCall(vm, getValue, &value, "v", NULL);
|
||||
WrenValue* getValue = wrenMakeCallHandle(vm, "getValue()");
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenCall(vm, getValue);
|
||||
WrenValue* value = wrenGetSlotValue(vm, 0);
|
||||
|
||||
// Different argument types.
|
||||
wrenCall(vm, two, NULL, "bb", true, false);
|
||||
wrenCall(vm, two, NULL, "dd", 1.2, 3.4);
|
||||
wrenCall(vm, two, NULL, "ii", 3, 4);
|
||||
wrenCall(vm, two, NULL, "ss", "string", "another");
|
||||
wrenCall(vm, two, NULL, "vv", NULL, value);
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotBool(vm, 1, true);
|
||||
wrenSetSlotBool(vm, 2, false);
|
||||
wrenCall(vm, two);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotDouble(vm, 1, 1.2);
|
||||
wrenSetSlotDouble(vm, 2, 3.4);
|
||||
wrenCall(vm, two);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotString(vm, 1, "string");
|
||||
wrenSetSlotString(vm, 2, "another");
|
||||
wrenCall(vm, two);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotNull(vm, 1);
|
||||
wrenSetSlotValue(vm, 2, value);
|
||||
wrenCall(vm, two);
|
||||
|
||||
// Truncate a string, or allow null bytes.
|
||||
wrenCall(vm, two, NULL, "aa", "string", 3, "b\0y\0t\0e", 7);
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotValue(vm, 0, callClass);
|
||||
wrenSetSlotBytes(vm, 1, "string", 3);
|
||||
wrenSetSlotBytes(vm, 2, "b\0y\0t\0e", 7);
|
||||
wrenCall(vm, two);
|
||||
|
||||
wrenReleaseValue(vm, callClass);
|
||||
wrenReleaseValue(vm, noParams);
|
||||
wrenReleaseValue(vm, zero);
|
||||
wrenReleaseValue(vm, one);
|
||||
|
||||
@ -20,13 +20,7 @@ class Call {
|
||||
System.print("two %(one) %(two)")
|
||||
}
|
||||
|
||||
static getValue(value) {
|
||||
// Return a new value if we aren't given one.
|
||||
if (value == null) return ["a", "b"]
|
||||
|
||||
// Otherwise print it.
|
||||
System.print(value)
|
||||
}
|
||||
static getValue() { ["a", "b"] }
|
||||
}
|
||||
|
||||
// expect: noParams
|
||||
@ -36,7 +30,6 @@ class Call {
|
||||
|
||||
// expect: two true false
|
||||
// expect: two 1.2 3.4
|
||||
// expect: two 3 4
|
||||
// expect: two string another
|
||||
// expect: two null [a, b]
|
||||
// expect: two str [98, 0, 121, 0, 116, 0, 101]
|
||||
|
||||
Reference in New Issue
Block a user