docs: rename WrenValue to WrenHandle across embedding docs and C API
Rename the `WrenValue` type to `WrenHandle` in the public C header, update all function signatures (`wrenMakeCallHandle`, `wrenCall`, `wrenReleaseHandle`), and rename the documentation page from "Slots and Values" to "Slots and Handles" with corresponding link updates throughout the embedding guide and module source files.
This commit is contained in:
+14
-14
@@ -14,9 +14,9 @@ typedef struct WrenVM WrenVM;
|
||||
// A handle to a Wren object.
|
||||
//
|
||||
// This lets code outside of the VM hold a persistent reference to an object.
|
||||
// After a value is acquired, and until it is released, this ensures the
|
||||
// garbage collector will not reclaim it.
|
||||
typedef struct WrenValue WrenValue;
|
||||
// After a handle is acquired, and until it is released, this ensures the
|
||||
// garbage collector will not reclaim the object it references.
|
||||
typedef struct WrenHandle WrenHandle;
|
||||
|
||||
// A generic allocation function that handles all explicit memory management
|
||||
// used by Wren. It's used like so:
|
||||
@@ -246,8 +246,8 @@ WrenInterpretResult wrenInterpret(WrenVM* vm, const char* source);
|
||||
// code using [wrenCall].
|
||||
//
|
||||
// When you are done with this handle, it must be released using
|
||||
// [wrenReleaseValue].
|
||||
WrenValue* wrenMakeCallHandle(WrenVM* vm, const char* signature);
|
||||
// [wrenReleaseHandle].
|
||||
WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature);
|
||||
|
||||
// Calls [method], using the receiver and arguments previously set up on the
|
||||
// stack.
|
||||
@@ -259,17 +259,17 @@ WrenValue* wrenMakeCallHandle(WrenVM* vm, const char* signature);
|
||||
// signature.
|
||||
//
|
||||
// After this returns, you can access the return value from slot 0 on the stack.
|
||||
WrenInterpretResult wrenCall(WrenVM* vm, WrenValue* method);
|
||||
WrenInterpretResult wrenCall(WrenVM* vm, WrenHandle* method);
|
||||
|
||||
// Releases the reference stored in [value]. After calling this, [value] can no
|
||||
// longer be used.
|
||||
void wrenReleaseValue(WrenVM* vm, WrenValue* value);
|
||||
// Releases the reference stored in [handle]. After calling this, [handle] can
|
||||
// no longer be used.
|
||||
void wrenReleaseHandle(WrenVM* vm, WrenHandle* handle);
|
||||
|
||||
// The following functions are intended to be called from foreign methods or
|
||||
// finalizers. The interface Wren provides to a foreign method is like a
|
||||
// register machine: you are given a numbered array of slots that values can be
|
||||
// read from and written to. Values always live in a slot (unless explicitly
|
||||
// captured using wrenGetSlotValue(), which ensures the garbage collector can
|
||||
// captured using wrenGetSlotHandle(), which ensures the garbage collector can
|
||||
// find them.
|
||||
//
|
||||
// When your foreign function is called, you are given one slot for the receiver
|
||||
@@ -357,8 +357,8 @@ const char* wrenGetSlotString(WrenVM* vm, int slot);
|
||||
// Creates a handle for the value stored in [slot].
|
||||
//
|
||||
// This will prevent the object that is referred to from being garbage collected
|
||||
// until the handle is released by calling [wrenReleaseValue()].
|
||||
WrenValue* wrenGetSlotValue(WrenVM* vm, int slot);
|
||||
// until the handle is released by calling [wrenReleaseHandle()].
|
||||
WrenHandle* wrenGetSlotHandle(WrenVM* vm, int slot);
|
||||
|
||||
// The following functions provide the return value for a foreign method back
|
||||
// to Wren. Like above, they may only be called during a foreign call invoked
|
||||
@@ -406,10 +406,10 @@ void wrenSetSlotNull(WrenVM* vm, int slot);
|
||||
// should use [wrenSetSlotBytes()] instead.
|
||||
void wrenSetSlotString(WrenVM* vm, int slot, const char* text);
|
||||
|
||||
// Stores the value captured in [value] in [slot].
|
||||
// Stores the value captured in [handle] in [slot].
|
||||
//
|
||||
// This does not release the handle for the value.
|
||||
void wrenSetSlotValue(WrenVM* vm, int slot, WrenValue* value);
|
||||
void wrenSetSlotHandle(WrenVM* vm, int slot, WrenHandle* handle);
|
||||
|
||||
// Takes the value stored at [elementSlot] and inserts it into the list stored
|
||||
// at [listSlot] at [index].
|
||||
|
||||
+28
-28
@@ -28,20 +28,20 @@
|
||||
|
||||
typedef struct sFileRequestData
|
||||
{
|
||||
WrenValue* fiber;
|
||||
WrenHandle* fiber;
|
||||
uv_buf_t buffer;
|
||||
} FileRequestData;
|
||||
|
||||
static const int stdinDescriptor = 0;
|
||||
|
||||
// Handle to the Stat class object.
|
||||
static WrenValue* statClass = NULL;
|
||||
static WrenHandle* statClass = NULL;
|
||||
|
||||
// Handle to the Stdin class object.
|
||||
static WrenValue* stdinClass = NULL;
|
||||
static WrenHandle* stdinClass = NULL;
|
||||
|
||||
// Handle to an onData_() method call. Called when libuv provides data on stdin.
|
||||
static WrenValue* stdinOnData = NULL;
|
||||
static WrenHandle* stdinOnData = NULL;
|
||||
|
||||
// The stream used to read from stdin. Initialized on the first read.
|
||||
static uv_stream_t* stdinStream = NULL;
|
||||
@@ -61,13 +61,13 @@ static void shutdownStdin()
|
||||
|
||||
if (stdinClass != NULL)
|
||||
{
|
||||
wrenReleaseValue(getVM(), stdinClass);
|
||||
wrenReleaseHandle(getVM(), stdinClass);
|
||||
stdinClass = NULL;
|
||||
}
|
||||
|
||||
if (stdinOnData != NULL)
|
||||
{
|
||||
wrenReleaseValue(getVM(), stdinOnData);
|
||||
wrenReleaseHandle(getVM(), stdinOnData);
|
||||
stdinOnData = NULL;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void ioShutdown()
|
||||
|
||||
if (statClass != NULL)
|
||||
{
|
||||
wrenReleaseValue(getVM(), statClass);
|
||||
wrenReleaseHandle(getVM(), statClass);
|
||||
statClass = NULL;
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ static bool handleRequestError(uv_fs_t* request)
|
||||
if (request->result >= 0) return false;
|
||||
|
||||
FileRequestData* data = (FileRequestData*)request->data;
|
||||
WrenValue* fiber = (WrenValue*)data->fiber;
|
||||
WrenHandle* fiber = (WrenHandle*)data->fiber;
|
||||
|
||||
schedulerResumeError(fiber, uv_strerror((int)request->result));
|
||||
|
||||
@@ -105,7 +105,7 @@ static bool handleRequestError(uv_fs_t* request)
|
||||
}
|
||||
|
||||
// Allocates a new request that resumes [fiber] when it completes.
|
||||
uv_fs_t* createRequest(WrenValue* fiber)
|
||||
uv_fs_t* createRequest(WrenHandle* fiber)
|
||||
{
|
||||
uv_fs_t* request = (uv_fs_t*)malloc(sizeof(uv_fs_t));
|
||||
|
||||
@@ -119,10 +119,10 @@ uv_fs_t* createRequest(WrenValue* fiber)
|
||||
// Releases resources used by [request].
|
||||
//
|
||||
// Returns the fiber that should be resumed after [request] completes.
|
||||
WrenValue* freeRequest(uv_fs_t* request)
|
||||
WrenHandle* freeRequest(uv_fs_t* request)
|
||||
{
|
||||
FileRequestData* data = (FileRequestData*)request->data;
|
||||
WrenValue* fiber = data->fiber;
|
||||
WrenHandle* fiber = data->fiber;
|
||||
|
||||
free(data);
|
||||
uv_fs_req_cleanup(request);
|
||||
@@ -154,7 +154,7 @@ static void directoryListCallback(uv_fs_t* request)
|
||||
void directoryList(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 2));
|
||||
|
||||
// TODO: Check return.
|
||||
uv_fs_scandir(getLoop(), request, path, 0, directoryListCallback);
|
||||
@@ -189,7 +189,7 @@ static void fileDeleteCallback(uv_fs_t* request)
|
||||
void fileDelete(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 2));
|
||||
|
||||
// TODO: Check return.
|
||||
uv_fs_unlink(getLoop(), request, path, fileDeleteCallback);
|
||||
@@ -227,7 +227,7 @@ void fileOpen(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
int flags = (int)wrenGetSlotDouble(vm, 2);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 3));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 3));
|
||||
|
||||
// TODO: Allow controlling access.
|
||||
uv_fs_open(getLoop(), request, path, mapFileFlags(flags), S_IRUSR | S_IWUSR,
|
||||
@@ -248,7 +248,7 @@ static void fileSizeCallback(uv_fs_t* request)
|
||||
void fileSizePath(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 2));
|
||||
uv_fs_stat(getLoop(), request, path, fileSizeCallback);
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ void fileClose(WrenVM* vm)
|
||||
// Mark it closed immediately.
|
||||
*foreign = -1;
|
||||
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 1));
|
||||
uv_fs_close(getLoop(), request, fd, fileCloseCallback);
|
||||
wrenSetSlotBool(vm, 0, false);
|
||||
}
|
||||
@@ -307,7 +307,7 @@ static void fileReadBytesCallback(uv_fs_t* request)
|
||||
|
||||
void fileReadBytes(WrenVM* vm)
|
||||
{
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 3));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 3));
|
||||
|
||||
int fd = *(int*)wrenGetSlotForeign(vm, 0);
|
||||
// TODO: Assert fd != -1.
|
||||
@@ -336,7 +336,7 @@ static void realPathCallback(uv_fs_t* request)
|
||||
void fileRealPath(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 2));
|
||||
uv_fs_realpath(getLoop(), request, path, realPathCallback);
|
||||
}
|
||||
|
||||
@@ -353,11 +353,11 @@ static void statCallback(uv_fs_t* request)
|
||||
if (statClass == NULL)
|
||||
{
|
||||
wrenGetVariable(vm, "io", "Stat", 0);
|
||||
statClass = wrenGetSlotValue(vm, 0);
|
||||
statClass = wrenGetSlotHandle(vm, 0);
|
||||
}
|
||||
|
||||
// Create a foreign Stat object to store the stat struct.
|
||||
wrenSetSlotValue(vm, 2, statClass);
|
||||
wrenSetSlotHandle(vm, 2, statClass);
|
||||
wrenSetSlotNewForeign(vm, 2, 2, sizeof(uv_stat_t));
|
||||
|
||||
// Copy the stat data.
|
||||
@@ -371,14 +371,14 @@ static void statCallback(uv_fs_t* request)
|
||||
void fileStat(WrenVM* vm)
|
||||
{
|
||||
int fd = *(int*)wrenGetSlotForeign(vm, 0);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 1));
|
||||
uv_fs_fstat(getLoop(), request, fd, statCallback);
|
||||
}
|
||||
|
||||
void fileSize(WrenVM* vm)
|
||||
{
|
||||
int fd = *(int*)wrenGetSlotForeign(vm, 0);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 1));
|
||||
uv_fs_fstat(getLoop(), request, fd, fileSizeCallback);
|
||||
}
|
||||
|
||||
@@ -398,12 +398,12 @@ void fileWriteBytes(WrenVM* vm)
|
||||
int length;
|
||||
const char* bytes = wrenGetSlotBytes(vm, 1, &length);
|
||||
size_t offset = (size_t)wrenGetSlotDouble(vm, 2);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 3));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 3));
|
||||
|
||||
FileRequestData* data = (FileRequestData*)request->data;
|
||||
|
||||
data->buffer.len = length;
|
||||
// TODO: Instead of copying, just create a WrenValue for the byte string and
|
||||
// TODO: Instead of copying, just create a WrenHandle for the byte string and
|
||||
// hold on to it in the request until the write is done.
|
||||
// TODO: Handle allocation failure.
|
||||
data->buffer.base = (char*)malloc(length);
|
||||
@@ -416,7 +416,7 @@ void fileWriteBytes(WrenVM* vm)
|
||||
void statPath(WrenVM* vm)
|
||||
{
|
||||
const char* path = wrenGetSlotString(vm, 1);
|
||||
uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
|
||||
uv_fs_t* request = createRequest(wrenGetSlotHandle(vm, 2));
|
||||
uv_fs_stat(getLoop(), request, path, statCallback);
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ static void stdinReadCallback(uv_stream_t* stream, ssize_t numRead,
|
||||
{
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "io", "Stdin", 0);
|
||||
stdinClass = wrenGetSlotValue(vm, 0);
|
||||
stdinClass = wrenGetSlotHandle(vm, 0);
|
||||
}
|
||||
|
||||
if (stdinOnData == NULL)
|
||||
@@ -568,7 +568,7 @@ static void stdinReadCallback(uv_stream_t* stream, ssize_t numRead,
|
||||
if (numRead == UV_EOF)
|
||||
{
|
||||
wrenEnsureSlots(vm, 2);
|
||||
wrenSetSlotValue(vm, 0, stdinClass);
|
||||
wrenSetSlotHandle(vm, 0, stdinClass);
|
||||
wrenSetSlotNull(vm, 1);
|
||||
wrenCall(vm, stdinOnData);
|
||||
|
||||
@@ -582,7 +582,7 @@ static void stdinReadCallback(uv_stream_t* stream, ssize_t numRead,
|
||||
// embedding API supported a way to *give* it bytes that were previously
|
||||
// allocated using Wren's own allocator.
|
||||
wrenEnsureSlots(vm, 2);
|
||||
wrenSetSlotValue(vm, 0, stdinClass);
|
||||
wrenSetSlotHandle(vm, 0, stdinClass);
|
||||
wrenSetSlotBytes(vm, 1, buffer->base, numRead);
|
||||
wrenCall(vm, stdinOnData);
|
||||
|
||||
|
||||
+15
-15
@@ -8,16 +8,16 @@
|
||||
#include "vm.h"
|
||||
|
||||
// A handle to the "Scheduler" class object. Used to call static methods on it.
|
||||
static WrenValue* schedulerClass;
|
||||
static WrenHandle* schedulerClass;
|
||||
|
||||
// This method resumes a fiber that is suspended waiting on an asynchronous
|
||||
// operation. The first resumes it with zero arguments, and the second passes
|
||||
// one.
|
||||
static WrenValue* resume1;
|
||||
static WrenValue* resume2;
|
||||
static WrenValue* resumeError;
|
||||
static WrenHandle* resume1;
|
||||
static WrenHandle* resume2;
|
||||
static WrenHandle* resumeError;
|
||||
|
||||
static void resume(WrenValue* method)
|
||||
static void resume(WrenHandle* method)
|
||||
{
|
||||
WrenInterpretResult result = wrenCall(getVM(), method);
|
||||
|
||||
@@ -34,20 +34,20 @@ void schedulerCaptureMethods(WrenVM* vm)
|
||||
{
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "scheduler", "Scheduler", 0);
|
||||
schedulerClass = wrenGetSlotValue(vm, 0);
|
||||
schedulerClass = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
resume1 = wrenMakeCallHandle(vm, "resume_(_)");
|
||||
resume2 = wrenMakeCallHandle(vm, "resume_(_,_)");
|
||||
resumeError = wrenMakeCallHandle(vm, "resumeError_(_,_)");
|
||||
}
|
||||
|
||||
void schedulerResume(WrenValue* fiber, bool hasArgument)
|
||||
void schedulerResume(WrenHandle* fiber, bool hasArgument)
|
||||
{
|
||||
WrenVM* vm = getVM();
|
||||
wrenEnsureSlots(vm, 2 + (hasArgument ? 1 : 0));
|
||||
wrenSetSlotValue(vm, 0, schedulerClass);
|
||||
wrenSetSlotValue(vm, 1, fiber);
|
||||
wrenReleaseValue(vm, fiber);
|
||||
wrenSetSlotHandle(vm, 0, schedulerClass);
|
||||
wrenSetSlotHandle(vm, 1, fiber);
|
||||
wrenReleaseHandle(vm, fiber);
|
||||
|
||||
// If we don't need to wait for an argument to be stored on the stack, resume
|
||||
// it now.
|
||||
@@ -59,7 +59,7 @@ void schedulerFinishResume()
|
||||
resume(resume2);
|
||||
}
|
||||
|
||||
void schedulerResumeError(WrenValue* fiber, const char* error)
|
||||
void schedulerResumeError(WrenHandle* fiber, const char* error)
|
||||
{
|
||||
schedulerResume(fiber, true);
|
||||
wrenSetSlotString(getVM(), 2, error);
|
||||
@@ -72,8 +72,8 @@ void schedulerShutdown()
|
||||
if (schedulerClass == NULL) return;
|
||||
|
||||
WrenVM* vm = getVM();
|
||||
wrenReleaseValue(vm, schedulerClass);
|
||||
wrenReleaseValue(vm, resume1);
|
||||
wrenReleaseValue(vm, resume2);
|
||||
wrenReleaseValue(vm, resumeError);
|
||||
wrenReleaseHandle(vm, schedulerClass);
|
||||
wrenReleaseHandle(vm, resume1);
|
||||
wrenReleaseHandle(vm, resume2);
|
||||
wrenReleaseHandle(vm, resumeError);
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
// on the stack and then call [schedulerFinishResume] to complete the call.
|
||||
//
|
||||
// Otherwise, the call resumes immediately. Releases [fiber] when called.
|
||||
void schedulerResume(WrenValue* fiber, bool hasArgument);
|
||||
void schedulerResume(WrenHandle* fiber, bool hasArgument);
|
||||
|
||||
void schedulerFinishResume();
|
||||
void schedulerResumeError(WrenValue* fiber, const char* error);
|
||||
void schedulerResumeError(WrenHandle* fiber, const char* error);
|
||||
|
||||
void schedulerShutdown();
|
||||
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ static void timerCloseCallback(uv_handle_t* handle)
|
||||
// Called by libuv when the timer has completed.
|
||||
static void timerCallback(uv_timer_t* handle)
|
||||
{
|
||||
WrenValue* fiber = (WrenValue*)handle->data;
|
||||
WrenHandle* fiber = (WrenHandle*)handle->data;
|
||||
|
||||
// Tell libuv that we don't need the timer anymore.
|
||||
uv_close((uv_handle_t*)handle, timerCloseCallback);
|
||||
@@ -28,7 +28,7 @@ static void timerCallback(uv_timer_t* handle)
|
||||
void timerStartTimer(WrenVM* vm)
|
||||
{
|
||||
int milliseconds = (int)wrenGetSlotDouble(vm, 1);
|
||||
WrenValue* fiber = wrenGetSlotValue(vm, 2);
|
||||
WrenHandle* fiber = wrenGetSlotHandle(vm, 2);
|
||||
|
||||
// Store the fiber to resume when the timer completes.
|
||||
uv_timer_t* handle = (uv_timer_t*)malloc(sizeof(uv_timer_t));
|
||||
|
||||
+31
-33
@@ -99,7 +99,7 @@ void wrenFreeVM(WrenVM* vm)
|
||||
// Tell the user if they didn't free any handles. We don't want to just free
|
||||
// them here because the host app may still have pointers to them that they
|
||||
// may try to use. Better to tell them about the bug early.
|
||||
ASSERT(vm->valueHandles == NULL, "All values have not been released.");
|
||||
ASSERT(vm->handles == NULL, "All handles have not been released.");
|
||||
|
||||
wrenSymbolTableClear(vm, &vm->methodNames);
|
||||
|
||||
@@ -138,12 +138,12 @@ void wrenCollectGarbage(WrenVM* vm)
|
||||
// The current fiber.
|
||||
wrenGrayObj(vm, (Obj*)vm->fiber);
|
||||
|
||||
// The value handles.
|
||||
for (WrenValue* value = vm->valueHandles;
|
||||
value != NULL;
|
||||
value = value->next)
|
||||
// The handles.
|
||||
for (WrenHandle* handle = vm->handles;
|
||||
handle != NULL;
|
||||
handle = handle->next)
|
||||
{
|
||||
wrenGrayValue(vm, value->value);
|
||||
wrenGrayValue(vm, handle->value);
|
||||
}
|
||||
|
||||
// Any object the compiler is using (if there is one).
|
||||
@@ -1195,7 +1195,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
|
||||
#undef READ_SHORT
|
||||
}
|
||||
|
||||
WrenValue* wrenMakeCallHandle(WrenVM* vm, const char* signature)
|
||||
WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature)
|
||||
{
|
||||
ASSERT(signature != NULL, "Signature cannot be NULL.");
|
||||
|
||||
@@ -1231,7 +1231,7 @@ WrenValue* wrenMakeCallHandle(WrenVM* vm, const char* signature)
|
||||
|
||||
// Wrap the function in a closure and then in a handle. Do this here so it
|
||||
// doesn't get collected as we fill it in.
|
||||
WrenValue* value = wrenCaptureValue(vm, OBJ_VAL(fn));
|
||||
WrenHandle* value = wrenMakeHandle(vm, OBJ_VAL(fn));
|
||||
value->value = OBJ_VAL(wrenNewClosure(vm, fn));
|
||||
|
||||
wrenByteBufferWrite(vm, &fn->code, (uint8_t)(CODE_CALL_0 + numParams));
|
||||
@@ -1245,7 +1245,7 @@ WrenValue* wrenMakeCallHandle(WrenVM* vm, const char* signature)
|
||||
return value;
|
||||
}
|
||||
|
||||
WrenInterpretResult wrenCall(WrenVM* vm, WrenValue* method)
|
||||
WrenInterpretResult wrenCall(WrenVM* vm, WrenHandle* method)
|
||||
{
|
||||
ASSERT(method != NULL, "Method cannot be NULL.");
|
||||
ASSERT(IS_CLOSURE(method->value), "Method must be a method handle.");
|
||||
@@ -1266,42 +1266,42 @@ WrenInterpretResult wrenCall(WrenVM* vm, WrenValue* method)
|
||||
return runInterpreter(vm, vm->fiber);
|
||||
}
|
||||
|
||||
WrenValue* wrenCaptureValue(WrenVM* vm, Value value)
|
||||
WrenHandle* wrenMakeHandle(WrenVM* vm, Value value)
|
||||
{
|
||||
if (IS_OBJ(value)) wrenPushRoot(vm, AS_OBJ(value));
|
||||
|
||||
// Make a handle for it.
|
||||
WrenValue* wrappedValue = ALLOCATE(vm, WrenValue);
|
||||
wrappedValue->value = value;
|
||||
WrenHandle* handle = ALLOCATE(vm, WrenHandle);
|
||||
handle->value = value;
|
||||
|
||||
if (IS_OBJ(value)) wrenPopRoot(vm);
|
||||
|
||||
// Add it to the front of the linked list of handles.
|
||||
if (vm->valueHandles != NULL) vm->valueHandles->prev = wrappedValue;
|
||||
wrappedValue->prev = NULL;
|
||||
wrappedValue->next = vm->valueHandles;
|
||||
vm->valueHandles = wrappedValue;
|
||||
if (vm->handles != NULL) vm->handles->prev = handle;
|
||||
handle->prev = NULL;
|
||||
handle->next = vm->handles;
|
||||
vm->handles = handle;
|
||||
|
||||
return wrappedValue;
|
||||
return handle;
|
||||
}
|
||||
|
||||
void wrenReleaseValue(WrenVM* vm, WrenValue* value)
|
||||
void wrenReleaseHandle(WrenVM* vm, WrenHandle* handle)
|
||||
{
|
||||
ASSERT(value != NULL, "Value cannot be NULL.");
|
||||
ASSERT(handle != NULL, "Handle cannot be NULL.");
|
||||
|
||||
// Update the VM's head pointer if we're releasing the first handle.
|
||||
if (vm->valueHandles == value) vm->valueHandles = value->next;
|
||||
if (vm->handles == handle) vm->handles = handle->next;
|
||||
|
||||
// Unlink it from the list.
|
||||
if (value->prev != NULL) value->prev->next = value->next;
|
||||
if (value->next != NULL) value->next->prev = value->prev;
|
||||
if (handle->prev != NULL) handle->prev->next = handle->next;
|
||||
if (handle->next != NULL) handle->next->prev = handle->prev;
|
||||
|
||||
// Clear it out. This isn't strictly necessary since we're going to free it,
|
||||
// but it makes for easier debugging.
|
||||
value->prev = NULL;
|
||||
value->next = NULL;
|
||||
value->value = NULL_VAL;
|
||||
DEALLOCATE(vm, value);
|
||||
handle->prev = NULL;
|
||||
handle->next = NULL;
|
||||
handle->value = NULL_VAL;
|
||||
DEALLOCATE(vm, handle);
|
||||
}
|
||||
|
||||
WrenInterpretResult wrenInterpret(WrenVM* vm, const char* source)
|
||||
@@ -1555,10 +1555,10 @@ const char* wrenGetSlotString(WrenVM* vm, int slot)
|
||||
return AS_CSTRING(vm->apiStack[slot]);
|
||||
}
|
||||
|
||||
WrenValue* wrenGetSlotValue(WrenVM* vm, int slot)
|
||||
WrenHandle* wrenGetSlotHandle(WrenVM* vm, int slot)
|
||||
{
|
||||
validateApiSlot(vm, slot);
|
||||
return wrenCaptureValue(vm, vm->apiStack[slot]);
|
||||
return wrenMakeHandle(vm, vm->apiStack[slot]);
|
||||
}
|
||||
|
||||
// Stores [value] in [slot] in the foreign call stack.
|
||||
@@ -1616,11 +1616,11 @@ void wrenSetSlotString(WrenVM* vm, int slot, const char* text)
|
||||
setSlot(vm, slot, wrenNewString(vm, text, strlen(text)));
|
||||
}
|
||||
|
||||
void wrenSetSlotValue(WrenVM* vm, int slot, WrenValue* value)
|
||||
void wrenSetSlotHandle(WrenVM* vm, int slot, WrenHandle* handle)
|
||||
{
|
||||
ASSERT(value != NULL, "Value cannot be NULL.");
|
||||
ASSERT(handle != NULL, "Handle cannot be NULL.");
|
||||
|
||||
setSlot(vm, slot, value->value);
|
||||
setSlot(vm, slot, handle->value);
|
||||
}
|
||||
|
||||
void wrenInsertInList(WrenVM* vm, int listSlot, int index, int elementSlot)
|
||||
@@ -1639,8 +1639,6 @@ void wrenInsertInList(WrenVM* vm, int listSlot, int index, int elementSlot)
|
||||
wrenListInsert(vm, list, vm->apiStack[elementSlot], index);
|
||||
}
|
||||
|
||||
// TODO: Maybe just have this always return a WrenValue* instead of having to
|
||||
// deal with slots?
|
||||
void wrenGetVariable(WrenVM* vm, const char* module, const char* name,
|
||||
int slot)
|
||||
{
|
||||
|
||||
+8
-8
@@ -20,12 +20,12 @@ typedef enum
|
||||
// A handle to a value, basically just a linked list of extra GC roots.
|
||||
//
|
||||
// Note that even non-heap-allocated values can be stored here.
|
||||
struct WrenValue
|
||||
struct WrenHandle
|
||||
{
|
||||
Value value;
|
||||
|
||||
WrenValue* prev;
|
||||
WrenValue* next;
|
||||
WrenHandle* prev;
|
||||
WrenHandle* next;
|
||||
};
|
||||
|
||||
struct WrenVM
|
||||
@@ -80,9 +80,9 @@ struct WrenVM
|
||||
|
||||
int numTempRoots;
|
||||
|
||||
// Pointer to the first node in the linked list of active value handles or
|
||||
// NULL if there are no handles.
|
||||
WrenValue* valueHandles;
|
||||
// Pointer to the first node in the linked list of active handles or NULL if
|
||||
// there are none.
|
||||
WrenHandle* handles;
|
||||
|
||||
// Pointer to the bottom of the range of stack slots available for use from
|
||||
// the C API. During a foreign method, this will be in the stack of the fiber
|
||||
@@ -128,8 +128,8 @@ void* wrenReallocate(WrenVM* vm, void* memory, size_t oldSize, size_t newSize);
|
||||
// Invoke the finalizer for the foreign object referenced by [foreign].
|
||||
void wrenFinalizeForeign(WrenVM* vm, ObjForeign* foreign);
|
||||
|
||||
// Creates a new [WrenValue] for [value].
|
||||
WrenValue* wrenCaptureValue(WrenVM* vm, Value value);
|
||||
// Creates a new [WrenHandle] for [value].
|
||||
WrenHandle* wrenMakeHandle(WrenVM* vm, Value value);
|
||||
|
||||
// Executes [source] in the context of [module].
|
||||
WrenInterpretResult wrenInterpretInModule(WrenVM* vm, const char* module,
|
||||
|
||||
Reference in New Issue
Block a user