forked from Mirror/wren
Add API to get the type of object in a slot.
This commit is contained in:
@ -162,12 +162,30 @@ typedef struct
|
|||||||
int heapGrowthPercent;
|
int heapGrowthPercent;
|
||||||
} WrenConfiguration;
|
} WrenConfiguration;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
WREN_RESULT_SUCCESS,
|
WREN_RESULT_SUCCESS,
|
||||||
WREN_RESULT_COMPILE_ERROR,
|
WREN_RESULT_COMPILE_ERROR,
|
||||||
WREN_RESULT_RUNTIME_ERROR
|
WREN_RESULT_RUNTIME_ERROR
|
||||||
} WrenInterpretResult;
|
} WrenInterpretResult;
|
||||||
|
|
||||||
|
// The type of an object stored in a slot.
|
||||||
|
//
|
||||||
|
// This is not necessarily the object's *class*, but instead its low level
|
||||||
|
// representation type.
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WREN_TYPE_BOOL,
|
||||||
|
WREN_TYPE_NUM,
|
||||||
|
WREN_TYPE_FOREIGN,
|
||||||
|
WREN_TYPE_LIST,
|
||||||
|
WREN_TYPE_NULL,
|
||||||
|
WREN_TYPE_STRING,
|
||||||
|
|
||||||
|
// The object is of a type that isn't accessible by the C API.
|
||||||
|
WREN_TYPE_UNKNOWN
|
||||||
|
} WrenType;
|
||||||
|
|
||||||
// Initializes [configuration] with all of its default values.
|
// Initializes [configuration] with all of its default values.
|
||||||
//
|
//
|
||||||
// Call this before setting the particular fields you care about.
|
// Call this before setting the particular fields you care about.
|
||||||
@ -263,6 +281,9 @@ int wrenGetSlotCount(WrenVM* vm);
|
|||||||
// It is an error to call this from a finalizer.
|
// It is an error to call this from a finalizer.
|
||||||
void wrenEnsureSlots(WrenVM* vm, int numSlots);
|
void wrenEnsureSlots(WrenVM* vm, int numSlots);
|
||||||
|
|
||||||
|
// Gets the type of the object in [slot].
|
||||||
|
WrenType wrenGetSlotType(WrenVM* vm, int slot);
|
||||||
|
|
||||||
// Reads a boolean value from [slot].
|
// Reads a boolean value from [slot].
|
||||||
//
|
//
|
||||||
// It is an error to call this if the slot does not contain a boolean value.
|
// It is an error to call this if the slot does not contain a boolean value.
|
||||||
|
|||||||
@ -1512,6 +1512,20 @@ static void validateApiSlot(WrenVM* vm, int slot)
|
|||||||
ASSERT(slot < wrenGetSlotCount(vm), "Not that many slots.");
|
ASSERT(slot < wrenGetSlotCount(vm), "Not that many slots.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the type of the object in [slot].
|
||||||
|
WrenType wrenGetSlotType(WrenVM* vm, int slot)
|
||||||
|
{
|
||||||
|
validateApiSlot(vm, slot);
|
||||||
|
if (IS_BOOL(vm->apiStack[slot])) return WREN_TYPE_BOOL;
|
||||||
|
if (IS_NUM(vm->apiStack[slot])) return WREN_TYPE_NUM;
|
||||||
|
if (IS_FOREIGN(vm->apiStack[slot])) return WREN_TYPE_FOREIGN;
|
||||||
|
if (IS_LIST(vm->apiStack[slot])) return WREN_TYPE_LIST;
|
||||||
|
if (IS_NULL(vm->apiStack[slot])) return WREN_TYPE_NULL;
|
||||||
|
if (IS_STRING(vm->apiStack[slot])) return WREN_TYPE_STRING;
|
||||||
|
|
||||||
|
return WREN_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
bool wrenGetSlotBool(WrenVM* vm, int slot)
|
bool wrenGetSlotBool(WrenVM* vm, int slot)
|
||||||
{
|
{
|
||||||
validateApiSlot(vm, slot);
|
validateApiSlot(vm, slot);
|
||||||
|
|||||||
@ -63,7 +63,15 @@ static WrenForeignClassMethods bindForeignClass(
|
|||||||
if (strcmp(module, "main") != 0) return methods;
|
if (strcmp(module, "main") != 0) return methods;
|
||||||
|
|
||||||
foreignClassBindClass(className, &methods);
|
foreignClassBindClass(className, &methods);
|
||||||
|
if (methods.allocate != NULL) return methods;
|
||||||
|
|
||||||
|
slotsBindClass(className, &methods);
|
||||||
|
if (methods.allocate != NULL) return methods;
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unknown foreign class '%s' for test '%s'\n", className, testName);
|
||||||
|
exit(1);
|
||||||
return methods;
|
return methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,6 +74,20 @@ static void setSlots(WrenVM* vm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void slotTypes(WrenVM* vm)
|
||||||
|
{
|
||||||
|
bool result =
|
||||||
|
wrenGetSlotType(vm, 1) == WREN_TYPE_BOOL &&
|
||||||
|
wrenGetSlotType(vm, 2) == WREN_TYPE_FOREIGN &&
|
||||||
|
wrenGetSlotType(vm, 3) == WREN_TYPE_LIST &&
|
||||||
|
wrenGetSlotType(vm, 4) == WREN_TYPE_NULL &&
|
||||||
|
wrenGetSlotType(vm, 5) == WREN_TYPE_NUM &&
|
||||||
|
wrenGetSlotType(vm, 6) == WREN_TYPE_STRING &&
|
||||||
|
wrenGetSlotType(vm, 7) == WREN_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
wrenSetSlotBool(vm, 0, result);
|
||||||
|
}
|
||||||
|
|
||||||
static void ensure(WrenVM* vm)
|
static void ensure(WrenVM* vm)
|
||||||
{
|
{
|
||||||
int before = wrenGetSlotCount(vm);
|
int before = wrenGetSlotCount(vm);
|
||||||
@ -134,13 +148,24 @@ static void ensureOutsideForeign(WrenVM* vm)
|
|||||||
wrenSetSlotString(vm, 0, result);
|
wrenSetSlotString(vm, 0, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void foreignClassAllocate(WrenVM* vm)
|
||||||
|
{
|
||||||
|
wrenSetSlotNewForeign(vm, 0, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
WrenForeignMethodFn slotsBindMethod(const char* signature)
|
WrenForeignMethodFn slotsBindMethod(const char* signature)
|
||||||
{
|
{
|
||||||
if (strcmp(signature, "static Slots.noSet") == 0) return noSet;
|
if (strcmp(signature, "static Slots.noSet") == 0) return noSet;
|
||||||
if (strcmp(signature, "static Slots.getSlots(_,_,_,_,_)") == 0) return getSlots;
|
if (strcmp(signature, "static Slots.getSlots(_,_,_,_,_)") == 0) return getSlots;
|
||||||
if (strcmp(signature, "static Slots.setSlots(_,_,_,_)") == 0) return setSlots;
|
if (strcmp(signature, "static Slots.setSlots(_,_,_,_)") == 0) return setSlots;
|
||||||
|
if (strcmp(signature, "static Slots.slotTypes(_,_,_,_,_,_,_)") == 0) return slotTypes;
|
||||||
if (strcmp(signature, "static Slots.ensure()") == 0) return ensure;
|
if (strcmp(signature, "static Slots.ensure()") == 0) return ensure;
|
||||||
if (strcmp(signature, "static Slots.ensureOutsideForeign()") == 0) return ensureOutsideForeign;
|
if (strcmp(signature, "static Slots.ensureOutsideForeign()") == 0) return ensureOutsideForeign;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void slotsBindClass(const char* className, WrenForeignClassMethods* methods)
|
||||||
|
{
|
||||||
|
methods->allocate = foreignClassAllocate;
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
#include "wren.h"
|
#include "wren.h"
|
||||||
|
|
||||||
WrenForeignMethodFn slotsBindMethod(const char* signature);
|
WrenForeignMethodFn slotsBindMethod(const char* signature);
|
||||||
|
void slotsBindClass(const char* className, WrenForeignClassMethods* methods);
|
||||||
|
|||||||
@ -2,10 +2,15 @@ class Slots {
|
|||||||
foreign static noSet
|
foreign static noSet
|
||||||
foreign static getSlots(bool, num, string, bytes, value)
|
foreign static getSlots(bool, num, string, bytes, value)
|
||||||
foreign static setSlots(a, b, c, d)
|
foreign static setSlots(a, b, c, d)
|
||||||
|
foreign static slotTypes(bool, foreignObj, list, nullObj, num, string, unknown)
|
||||||
foreign static ensure()
|
foreign static ensure()
|
||||||
foreign static ensureOutsideForeign()
|
foreign static ensureOutsideForeign()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreign class ForeignType {
|
||||||
|
construct new() {}
|
||||||
|
}
|
||||||
|
|
||||||
// If nothing is set in the return slot, it retains its previous value, the
|
// If nothing is set in the return slot, it retains its previous value, the
|
||||||
// receiver.
|
// receiver.
|
||||||
System.print(Slots.noSet == Slots) // expect: true
|
System.print(Slots.noSet == Slots) // expect: true
|
||||||
@ -17,6 +22,9 @@ System.print(Slots.getSlots(true, "by\0te", 12.34, "str", value) == value)
|
|||||||
System.print(Slots.setSlots(value, 0, 0, 0) == value)
|
System.print(Slots.setSlots(value, 0, 0, 0) == value)
|
||||||
// expect: true
|
// expect: true
|
||||||
|
|
||||||
|
System.print(Slots.slotTypes(false, ForeignType.new(), [], null, 1.2, "str", 1..2))
|
||||||
|
// expect: true
|
||||||
|
|
||||||
System.print(Slots.ensure())
|
System.print(Slots.ensure())
|
||||||
// expect: 1 -> 20 (190)
|
// expect: 1 -> 20 (190)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user