refactor: replace wrenReturn___() with wrenSetSlot___() for writing values to arbitrary slots

The old wrenReturn___() functions only wrote to slot 0 for return values. The new wrenSetSlot___() functions allow writing to any slot index, making them general-purpose for manipulating the foreign call stack. This change updates all call sites, removes the dedicated returns test suite in favor of slots tests, and adjusts the VM internals to treat slot 0 as the return position rather than using a separate return mechanism.
This commit is contained in:
Bob Nystrom
2015-12-16 21:00:13 +00:00
parent 234a98faef
commit 7535fed608
16 changed files with 215 additions and 152 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ static void arguments(WrenVM* vm)
result += wrenGetSlotDouble(vm, 3);
result += wrenGetSlotDouble(vm, 4);
wrenReturnDouble(vm, result);
wrenSetSlotDouble(vm, 0, result);
}
WrenForeignMethodFn benchmarkBindMethod(const char* signature)
+3 -3
View File
@@ -7,7 +7,7 @@ static int finalized = 0;
static void apiFinalized(WrenVM* vm)
{
wrenReturnDouble(vm, finalized);
wrenSetSlotDouble(vm, 0, finalized);
}
static void counterAllocate(WrenVM* vm)
@@ -27,7 +27,7 @@ static void counterIncrement(WrenVM* vm)
static void counterValue(WrenVM* vm)
{
double value = *(double*)wrenGetSlotForeign(vm, 0);
wrenReturnDouble(vm, value);
wrenSetSlotDouble(vm, 0, value);
}
static void pointAllocate(WrenVM* vm)
@@ -64,7 +64,7 @@ static void pointToString(WrenVM* vm)
char result[100];
sprintf(result, "(%g, %g, %g)",
coordinates[0], coordinates[1], coordinates[2]);
wrenReturnString(vm, result, (int)strlen(result));
wrenSetSlotString(vm, 0, result);
}
static void resourceAllocate(WrenVM* vm)
+2 -2
View File
@@ -7,7 +7,7 @@
#include "benchmark.h"
#include "call.h"
#include "foreign_class.h"
#include "returns.h"
#include "slots.h"
#include "value.h"
// The name of the currently executing API test.
@@ -36,7 +36,7 @@ static WrenForeignMethodFn bindForeignMethod(
method = foreignClassBindMethod(fullName);
if (method != NULL) return method;
method = returnsBindMethod(fullName);
method = slotsBindMethod(fullName);
if (method != NULL) return method;
method = valueBindMethod(fullName);
-51
View File
@@ -1,51 +0,0 @@
#include <string.h>
#include "returns.h"
static void implicitNull(WrenVM* vm)
{
// Do nothing.
}
static void returnInt(WrenVM* vm)
{
wrenReturnDouble(vm, 123456);
}
static void returnFloat(WrenVM* vm)
{
wrenReturnDouble(vm, 123.456);
}
static void returnTrue(WrenVM* vm)
{
wrenReturnBool(vm, true);
}
static void returnFalse(WrenVM* vm)
{
wrenReturnBool(vm, false);
}
static void returnString(WrenVM* vm)
{
wrenReturnString(vm, "a string", -1);
}
static void returnBytes(WrenVM* vm)
{
wrenReturnString(vm, "a\0b\0c", 5);
}
WrenForeignMethodFn returnsBindMethod(const char* signature)
{
if (strcmp(signature, "static Returns.implicitNull") == 0) return implicitNull;
if (strcmp(signature, "static Returns.returnInt") == 0) return returnInt;
if (strcmp(signature, "static Returns.returnFloat") == 0) return returnFloat;
if (strcmp(signature, "static Returns.returnTrue") == 0) return returnTrue;
if (strcmp(signature, "static Returns.returnFalse") == 0) return returnFalse;
if (strcmp(signature, "static Returns.returnString") == 0) return returnString;
if (strcmp(signature, "static Returns.returnBytes") == 0) return returnBytes;
return NULL;
}
-3
View File
@@ -1,3 +0,0 @@
#include "wren.h"
WrenForeignMethodFn returnsBindMethod(const char* signature);
-23
View File
@@ -1,23 +0,0 @@
class Returns {
foreign static implicitNull
foreign static returnInt
foreign static returnFloat
foreign static returnTrue
foreign static returnFalse
foreign static returnString
foreign static returnBytes
}
System.print(Returns.implicitNull == null) // expect: true
System.print(Returns.returnInt) // expect: 123456
System.print(Returns.returnFloat) // expect: 123.456
System.print(Returns.returnTrue) // expect: true
System.print(Returns.returnFalse) // expect: false
System.print(Returns.returnString) // expect: a string
System.print(Returns.returnBytes.bytes.toList) // expect: [97, 0, 98, 0, 99]
+83
View File
@@ -0,0 +1,83 @@
#include <string.h>
#include "slots.h"
static void noSet(WrenVM* vm)
{
// Do nothing.
}
static void getSlots(WrenVM* vm)
{
bool result = true;
if (wrenGetSlotBool(vm, 1) != true) result = false;
// TODO: Test wrenGetSlotForeign().
int length;
const char* bytes = wrenGetSlotBytes(vm, 2, &length);
if (length != 5) result = false;
if (memcmp(bytes, "by\0te", length) != 0) result = false;
if (wrenGetSlotDouble(vm, 3) != 12.34) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
WrenValue* value = wrenGetSlotValue(vm, 5);
if (result)
{
// Otherwise, return the value so we can tell if we captured it correctly.
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
}
static void setSlots(WrenVM* vm)
{
WrenValue* value = wrenGetSlotValue(vm, 1);
wrenSetSlotBool(vm, 1, true);
wrenSetSlotBytes(vm, 2, "by\0te", 5);
wrenSetSlotDouble(vm, 3, 12.34);
wrenSetSlotString(vm, 4, "str");
// TODO: wrenSetSlotNull().
// Read the slots back to make sure they were set correctly.
bool result = true;
if (wrenGetSlotBool(vm, 1) != true) result = false;
int length;
const char* bytes = wrenGetSlotBytes(vm, 2, &length);
if (length != 5) result = false;
if (memcmp(bytes, "by\0te", length) != 0) result = false;
if (wrenGetSlotDouble(vm, 3) != 12.34) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
if (result)
{
// Move the value into the return position.
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
}
WrenForeignMethodFn slotsBindMethod(const char* signature)
{
if (strcmp(signature, "static Slots.noSet") == 0) return noSet;
if (strcmp(signature, "static Slots.getSlots(_,_,_,_,_)") == 0) return getSlots;
if (strcmp(signature, "static Slots.setSlots(_,_,_,_)") == 0) return setSlots;
return NULL;
}
+3
View File
@@ -0,0 +1,3 @@
#include "wren.h"
WrenForeignMethodFn slotsBindMethod(const char* signature);
+16
View File
@@ -0,0 +1,16 @@
class Slots {
foreign static noSet
foreign static getSlots(bool, num, string, bytes, value)
foreign static setSlots(a, b, c, d)
}
// If nothing is set in the return slot, it retains its previous value, the
// receiver.
System.print(Slots.noSet == Slots) // expect: true
var value = ["value"]
System.print(Slots.getSlots(true, "by\0te", 12.34, "str", value) == value) // expect: true
System.print(Slots.setSlots(value, 0, 0, 0) == value) // expect: true
+1 -1
View File
@@ -11,7 +11,7 @@ static void setValue(WrenVM* vm)
static void getValue(WrenVM* vm)
{
wrenReturnValue(vm, value);
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}