void fileOpen(WrenVM* vm) { const char* path = wrenGetSlotString(vm, 1); uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2)); // TODO: Allow controlling flags and modes. uv_fs_open(getLoop(), request, path, O_RDONLY, 0, fileOpenCallback); }
void fileSize(WrenVM* vm) { uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1)); int fd = *(int*)wrenGetSlotForeign(vm, 0); // TODO: Assert fd != -1. uv_fs_fstat(getLoop(), request, fd, fileSizeCallback); }
void directoryList(WrenVM* vm) { const char* path = wrenGetSlotString(vm, 1); uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2)); // TODO: Check return. uv_fs_scandir(getLoop(), request, path, 0, directoryListCallback); }
void schedulerCaptureMethods(WrenVM* vm) { wrenEnsureSlots(vm, 1); wrenGetVariable(vm, "scheduler", "Scheduler", 0); schedulerClass = wrenGetSlotValue(vm, 0); resume1 = wrenMakeCallHandle(vm, "resume_(_)"); resume2 = wrenMakeCallHandle(vm, "resume_(_,_)"); resumeError = wrenMakeCallHandle(vm, "resumeError_(_,_)"); }
void fileReadBytes(WrenVM* vm) { uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 3)); int fd = *(int*)wrenGetSlotForeign(vm, 0); // TODO: Assert fd != -1. FileRequestData* data = (FileRequestData*)request->data; size_t length = (size_t)wrenGetSlotDouble(vm, 1); size_t offset = (size_t)wrenGetSlotDouble(vm, 2); data->buffer.len = length; data->buffer.base = (char*)malloc(length); uv_fs_read(getLoop(), request, fd, &data->buffer, 1, offset, fileReadBytesCallback); }
void fileClose(WrenVM* vm) { int* foreign = (int*)wrenGetSlotForeign(vm, 0); int fd = *foreign; // If it's already closed, we're done. if (fd == -1) { wrenSetSlotBool(vm, 0, true); return; } // Mark it closed immediately. *foreign = -1; uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 1)); uv_fs_close(getLoop(), request, fd, fileCloseCallback); wrenSetSlotBool(vm, 0, false); }
static void stdinReadCallback(uv_stream_t* stream, ssize_t numRead, const uv_buf_t* buffer) { WrenVM* vm = getVM(); if (stdinClass == NULL) { wrenEnsureSlots(vm, 1); wrenGetVariable(vm, "io", "Stdin", 0); stdinClass = wrenGetSlotValue(vm, 0); } if (stdinOnData == NULL) { stdinOnData = wrenMakeCallHandle(vm, "onData_(_)"); } // If stdin was closed, send null to let io.wren know. if (numRead == UV_EOF) { wrenEnsureSlots(vm, 2); wrenSetSlotValue(vm, 0, stdinClass); wrenSetSlotNull(vm, 1); wrenCall(vm, stdinOnData); shutdownStdin(); return; } // TODO: Handle other errors. // TODO: Having to copy the bytes here is a drag. It would be good if Wren's // 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); wrenSetSlotBytes(vm, 1, buffer->base, numRead); wrenCall(vm, stdinOnData); // TODO: Likewise, freeing this after we resume is lame. free(buffer->base); }
void callRunTests(WrenVM* vm) { wrenEnsureSlots(vm, 1); wrenGetVariable(vm, "main", "Call", 0); WrenValue* callClass = wrenGetSlotValue(vm, 0); WrenValue* noParams = wrenMakeCallHandle(vm, "noParams"); WrenValue* zero = wrenMakeCallHandle(vm, "zero()"); WrenValue* one = wrenMakeCallHandle(vm, "one(_)"); WrenValue* two = wrenMakeCallHandle(vm, "two(_,_)"); // Different arity. wrenEnsureSlots(vm, 1); wrenSetSlotValue(vm, 0, callClass); wrenCall(vm, noParams); wrenEnsureSlots(vm, 1); wrenSetSlotValue(vm, 0, callClass); wrenCall(vm, zero); wrenEnsureSlots(vm, 2); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotDouble(vm, 1, 1.0); wrenCall(vm, one); wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotDouble(vm, 1, 1.0); wrenSetSlotDouble(vm, 2, 2.0); wrenCall(vm, two); // Returning a value. WrenValue* getValue = wrenMakeCallHandle(vm, "getValue()"); wrenEnsureSlots(vm, 1); wrenSetSlotValue(vm, 0, callClass); wrenCall(vm, getValue); WrenValue* value = wrenGetSlotValue(vm, 0); // Different argument types. wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotBool(vm, 1, true); wrenSetSlotBool(vm, 2, false); wrenCall(vm, two); wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotDouble(vm, 1, 1.2); wrenSetSlotDouble(vm, 2, 3.4); wrenCall(vm, two); wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotString(vm, 1, "string"); wrenSetSlotString(vm, 2, "another"); wrenCall(vm, two); wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotNull(vm, 1); wrenSetSlotValue(vm, 2, value); wrenCall(vm, two); // Truncate a string, or allow null bytes. wrenEnsureSlots(vm, 3); wrenSetSlotValue(vm, 0, callClass); wrenSetSlotBytes(vm, 1, "string", 3); wrenSetSlotBytes(vm, 2, "b\0y\0t\0e", 7); wrenCall(vm, two); // Call ignores with extra temporary slots on stack. wrenEnsureSlots(vm, 10); wrenSetSlotValue(vm, 0, callClass); for (int i = 1; i < 10; i++) { wrenSetSlotDouble(vm, i, i * 0.1); } wrenCall(vm, one); wrenReleaseValue(vm, callClass); wrenReleaseValue(vm, noParams); wrenReleaseValue(vm, zero); wrenReleaseValue(vm, one); wrenReleaseValue(vm, two); wrenReleaseValue(vm, getValue); wrenReleaseValue(vm, value); }
void statPath(WrenVM* vm) { const char* path = wrenGetSlotString(vm, 1); uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2)); uv_fs_stat(getLoop(), request, path, statPathCallback); }