feat: expose wrenEnsureSlots API and rename foreignStackStart to apiStack for slot access outside foreign methods
Replace the internal `foreignStackStart` pointer with a public `apiStack` field that tracks the base of available C API slots. Extract the static `ensureStack` helper into a non-static `wrenEnsureStack` function declared in the header, enabling `wrenEnsureSlots()` to create a fiber and stack when called outside a foreign method. Update `callForeign` to use `apiStack` and adjust `metaCompile` to write results through the new pointer. Add a `ensureOutsideForeign` test that allocates slots on a fresh VM, verifies slot count grows from 0 to 20, and exercises all 20 slots with double values to confirm the stack is correctly initialized and usable.
This commit is contained in:
+36
-1
@@ -94,7 +94,41 @@ static void ensure(WrenVM* vm)
|
||||
{
|
||||
sum += (int)wrenGetSlotDouble(vm, i);
|
||||
}
|
||||
|
||||
|
||||
char result[100];
|
||||
sprintf(result, "%d -> %d (%d)", before, after, sum);
|
||||
wrenSetSlotString(vm, 0, result);
|
||||
}
|
||||
|
||||
static void ensureOutsideForeign(WrenVM* vm)
|
||||
{
|
||||
// To test the behavior outside of a foreign method (which we're currently
|
||||
// in), create a new separate VM.
|
||||
WrenConfiguration config;
|
||||
wrenInitConfiguration(&config);
|
||||
WrenVM* otherVM = wrenNewVM(&config);
|
||||
|
||||
int before = wrenGetSlotCount(otherVM);
|
||||
|
||||
wrenEnsureSlots(otherVM, 20);
|
||||
|
||||
int after = wrenGetSlotCount(otherVM);
|
||||
|
||||
// Use the slots to make sure they're available.
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
wrenSetSlotDouble(otherVM, i, i);
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
sum += (int)wrenGetSlotDouble(otherVM, i);
|
||||
}
|
||||
|
||||
wrenFreeVM(otherVM);
|
||||
|
||||
char result[100];
|
||||
sprintf(result, "%d -> %d (%d)", before, after, sum);
|
||||
wrenSetSlotString(vm, 0, result);
|
||||
@@ -106,6 +140,7 @@ WrenForeignMethodFn slotsBindMethod(const char* signature)
|
||||
if (strcmp(signature, "static Slots.getSlots(_,_,_,_,_)") == 0) return getSlots;
|
||||
if (strcmp(signature, "static Slots.setSlots(_,_,_,_)") == 0) return setSlots;
|
||||
if (strcmp(signature, "static Slots.ensure()") == 0) return ensure;
|
||||
if (strcmp(signature, "static Slots.ensureOutsideForeign()") == 0) return ensureOutsideForeign;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+10
-3
@@ -3,6 +3,7 @@ class Slots {
|
||||
foreign static getSlots(bool, num, string, bytes, value)
|
||||
foreign static setSlots(a, b, c, d)
|
||||
foreign static ensure()
|
||||
foreign static ensureOutsideForeign()
|
||||
}
|
||||
|
||||
// If nothing is set in the return slot, it retains its previous value, the
|
||||
@@ -10,8 +11,14 @@ class Slots {
|
||||
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.getSlots(true, "by\0te", 12.34, "str", value) == value)
|
||||
// expect: true
|
||||
|
||||
System.print(Slots.setSlots(value, 0, 0, 0) == value) // expect: true
|
||||
System.print(Slots.setSlots(value, 0, 0, 0) == value)
|
||||
// expect: true
|
||||
|
||||
System.print(Slots.ensure()) // expect: 1 -> 20 (190)
|
||||
System.print(Slots.ensure())
|
||||
// expect: 1 -> 20 (190)
|
||||
|
||||
System.print(Slots.ensureOutsideForeign())
|
||||
// expect: 0 -> 20 (190)
|
||||
|
||||
Reference in New Issue
Block a user