diff --git a/AUTHORS b/AUTHORS index b0a402e2..f85c823e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,3 +16,4 @@ Evan Hahn Starbeamrainbowlabs Alexander Roper Will Speak +Damien Radtke diff --git a/src/include/wren.h b/src/include/wren.h index 5598f60e..2d16109d 100644 --- a/src/include/wren.h +++ b/src/include/wren.h @@ -345,6 +345,12 @@ double wrenGetSlotDouble(WrenVM* vm, int slot); // foreign class. void* wrenGetSlotForeign(WrenVM* vm, int slot); +// Returns the size of the list stored in [slot]. +int wrenGetSlotListSize(WrenVM* vm, int slot); + +// Reads a value from the list in [slot]. +WrenValue* wrenGetSlotListValue(WrenVM* vm, int slot, int index); + // Reads a string from [slot]. // // The memory for the returned string is owned by Wren. You can inspect it diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index 00d113c2..7b758bd2 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -1547,6 +1547,26 @@ void* wrenGetSlotForeign(WrenVM* vm, int slot) return AS_FOREIGN(vm->apiStack[slot])->data; } +int wrenGetSlotListSize(WrenVM* vm, int slot) +{ + validateApiSlot(vm, slot); + ASSERT(IS_LIST(vm->apiStack[slot]), + "Slot must hold a list instance."); + + ValueBuffer elements = AS_LIST(vm->apiStack[slot])->elements; + return elements.count; +} + +WrenValue* wrenGetSlotListValue(WrenVM* vm, int slot, int index) +{ + validateApiSlot(vm, slot); + ASSERT(IS_LIST(vm->apiStack[slot]), + "Slot must hold a list instance."); + + ValueBuffer elements = AS_LIST(vm->apiStack[slot])->elements; + return wrenCaptureValue(vm, elements.data[index]); +} + const char* wrenGetSlotString(WrenVM* vm, int slot) { validateApiSlot(vm, slot); diff --git a/test/api/slots.c b/test/api/slots.c index 16dd9c18..27996452 100644 --- a/test/api/slots.c +++ b/test/api/slots.c @@ -153,6 +153,19 @@ static void foreignClassAllocate(WrenVM* vm) wrenSetSlotNewForeign(vm, 0, 0, 4); } +static void getListSize(WrenVM* vm) +{ + wrenSetSlotDouble(vm, 0, wrenGetSlotListSize(vm, 1)); +} + +static void getListValue(WrenVM* vm) +{ + int index = (int)wrenGetSlotDouble(vm, 2); + WrenValue* value = wrenGetSlotListValue(vm, 1, index); + wrenSetSlotValue(vm, 0, value); + wrenReleaseValue(vm, value); +} + WrenForeignMethodFn slotsBindMethod(const char* signature) { if (strcmp(signature, "static Slots.noSet") == 0) return noSet; @@ -161,6 +174,8 @@ WrenForeignMethodFn slotsBindMethod(const char* signature) if (strcmp(signature, "static Slots.slotTypes(_,_,_,_,_,_,_)") == 0) return slotTypes; if (strcmp(signature, "static Slots.ensure()") == 0) return ensure; if (strcmp(signature, "static Slots.ensureOutsideForeign()") == 0) return ensureOutsideForeign; + if (strcmp(signature, "static Slots.getListSize(_)") == 0) return getListSize; + if (strcmp(signature, "static Slots.getListValue(_,_)") == 0) return getListValue; return NULL; } @@ -168,4 +183,4 @@ WrenForeignMethodFn slotsBindMethod(const char* signature) void slotsBindClass(const char* className, WrenForeignClassMethods* methods) { methods->allocate = foreignClassAllocate; -} \ No newline at end of file +} diff --git a/test/api/slots.wren b/test/api/slots.wren index 1159ef3a..63ec2a4f 100644 --- a/test/api/slots.wren +++ b/test/api/slots.wren @@ -5,6 +5,8 @@ class Slots { foreign static slotTypes(bool, foreignObj, list, nullObj, num, string, unknown) foreign static ensure() foreign static ensureOutsideForeign() + foreign static getListSize(list) + foreign static getListValue(list, index) } foreign class ForeignType { @@ -30,3 +32,7 @@ System.print(Slots.ensure()) System.print(Slots.ensureOutsideForeign()) // expect: 0 -> 20 (190) + +var ducks = ["Huey", "Dewey", "Louie"] +System.print(Slots.getListSize(ducks)) // expect: 3 +System.print(Slots.getListValue(ducks, 1)) // expect: Dewey