feat: replace wrenAllocateForeign with wrenSetSlotNewForeign supporting arbitrary slot and class selection

The old wrenAllocateForeign was limited to slot 0 and the class at the top of the API stack. The new wrenSetSlotNewForeign takes explicit slot and classSlot parameters, allowing foreign objects to be created in any slot from any class. All internal and test call sites updated to use the new API.
This commit is contained in:
Bob Nystrom
2016-01-24 17:25:04 +00:00
parent 885570f0b6
commit 87334da1df
5 changed files with 31 additions and 28 deletions
+15 -14
View File
@@ -1357,20 +1357,6 @@ void wrenReleaseValue(WrenVM* vm, WrenValue* value)
DEALLOCATE(vm, value);
}
void* wrenAllocateForeign(WrenVM* vm, size_t size)
{
ASSERT(vm->apiStack != NULL, "Must be in foreign call.");
// TODO: Validate this. It can fail if the user calls this inside another
// foreign method, or calls one of the return functions.
ObjClass* classObj = AS_CLASS(vm->apiStack[0]);
ObjForeign* foreign = wrenNewForeign(vm, classObj, size);
vm->apiStack[0] = OBJ_VAL(foreign);
return (void*)foreign->data;
}
WrenInterpretResult wrenInterpret(WrenVM* vm, const char* source)
{
return wrenInterpretInModule(vm, "main", source);
@@ -1598,6 +1584,21 @@ void wrenSetSlotDouble(WrenVM* vm, int slot, double value)
setSlot(vm, slot, NUM_VAL(value));
}
void* wrenSetSlotNewForeign(WrenVM* vm, int slot, int classSlot, size_t size)
{
validateApiSlot(vm, slot);
validateApiSlot(vm, classSlot);
ASSERT(IS_CLASS(vm->apiStack[classSlot]), "Slot must hold a class.");
ObjClass* classObj = AS_CLASS(vm->apiStack[classSlot]);
ASSERT(classObj->numFields == -1, "Class must be a foreign class.");
ObjForeign* foreign = wrenNewForeign(vm, classObj, size);
vm->apiStack[slot] = OBJ_VAL(foreign);
return (void*)foreign->data;
}
void wrenSetSlotNewList(WrenVM* vm, int slot)
{
setSlot(vm, slot, OBJ_VAL(wrenNewList(vm, 0)));