From 02bcefcbe44cdb73efeebc9b2a9702c41a9674a9 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Wed, 22 Mar 2017 07:26:19 -0700 Subject: [PATCH] Add test for user data. Also moved the VM parameter in the error callback to be first like it is in other callbacks. --- src/cli/vm.c | 4 +- src/include/wren.h | 5 ++- src/vm/wren_compiler.c | 4 +- src/vm/wren_debug.c | 11 +++-- test/api/main.c | 4 ++ test/api/user_data.c | 51 +++++++++++++++++++++++ test/api/user_data.h | 3 ++ test/api/user_data.wren | 5 +++ util/xcode/wren.xcodeproj/project.pbxproj | 6 +++ 9 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 test/api/user_data.c create mode 100644 test/api/user_data.h create mode 100644 test/api/user_data.wren diff --git a/src/cli/vm.c b/src/cli/vm.c index 62d3f34e..ce3b42f9 100644 --- a/src/cli/vm.c +++ b/src/cli/vm.c @@ -154,8 +154,8 @@ static void write(WrenVM* vm, const char* text) fflush(stdout); } -static void reportError(WrenErrorType type, - const char* module, int line, const char* message, WrenVM* vm) +static void reportError(WrenVM* vm, WrenErrorType type, + const char* module, int line, const char* message) { switch (type) { diff --git a/src/include/wren.h b/src/include/wren.h index faebcbfa..bdcb6e13 100644 --- a/src/include/wren.h +++ b/src/include/wren.h @@ -96,7 +96,8 @@ typedef enum // Each of those has the module and line where the method or function is // defined and [message] is the name of the method or function. typedef void (*WrenErrorFn)( - WrenErrorType type, const char* module, int line, const char* message, WrenVM* vm); + WrenVM* vm, WrenErrorType type, const char* module, int line, + const char* message); typedef struct { @@ -207,7 +208,7 @@ typedef struct // If zero, defaults to 50. int heapGrowthPercent; - // User defined state data associated with the WrenVM. + // User-defined data associated with the VM. void* userData; } WrenConfiguration; diff --git a/src/vm/wren_compiler.c b/src/vm/wren_compiler.c index 6c342ef1..49ae0268 100644 --- a/src/vm/wren_compiler.c +++ b/src/vm/wren_compiler.c @@ -403,8 +403,8 @@ static void printError(Parser* parser, int line, const char* label, length += vsprintf(message + length, format, args); ASSERT(length < ERROR_MESSAGE_SIZE, "Error should not exceed buffer."); - parser->vm->config.errorFn(WREN_ERROR_COMPILE, - parser->module->name->value, line, message, parser->vm); + parser->vm->config.errorFn(parser->vm, WREN_ERROR_COMPILE, + parser->module->name->value, line, message); } // Outputs a compile or syntax error. This also marks the compilation as having diff --git a/src/vm/wren_debug.c b/src/vm/wren_debug.c index 7c38cc29..82297c7d 100644 --- a/src/vm/wren_debug.c +++ b/src/vm/wren_debug.c @@ -10,13 +10,15 @@ void wrenDebugPrintStackTrace(WrenVM* vm) ObjFiber* fiber = vm->fiber; if (IS_STRING(fiber->error)) { - vm->config.errorFn(WREN_ERROR_RUNTIME, NULL, -1, AS_CSTRING(fiber->error), vm); + vm->config.errorFn(vm, WREN_ERROR_RUNTIME, + NULL, -1, AS_CSTRING(fiber->error)); } else { // TODO: Print something a little useful here. Maybe the name of the error's // class? - vm->config.errorFn(WREN_ERROR_RUNTIME, NULL, -1, "[error object]", vm); + vm->config.errorFn(vm, WREN_ERROR_RUNTIME, + NULL, -1, "[error object]"); } for (int i = fiber->numFrames - 1; i >= 0; i--) @@ -34,8 +36,9 @@ void wrenDebugPrintStackTrace(WrenVM* vm) // -1 because IP has advanced past the instruction that it just executed. int line = fn->debug->sourceLines.data[frame->ip - fn->code.data - 1]; - vm->config.errorFn(WREN_ERROR_STACK_TRACE, fn->module->name->value, line, - fn->debug->name, vm); + vm->config.errorFn(vm, WREN_ERROR_STACK_TRACE, + fn->module->name->value, line, + fn->debug->name); } } diff --git a/test/api/main.c b/test/api/main.c index 8647b8f4..1557dd94 100644 --- a/test/api/main.c +++ b/test/api/main.c @@ -15,6 +15,7 @@ #include "reset_stack_after_call_abort.h" #include "reset_stack_after_foreign_construct.h" #include "slots.h" +#include "user_data.h" // The name of the currently executing API test. const char* testName; @@ -59,6 +60,9 @@ static WrenForeignMethodFn bindForeignMethod( method = slotsBindMethod(fullName); if (method != NULL) return method; + + method = userDataBindMethod(fullName); + if (method != NULL) return method; fprintf(stderr, "Unknown foreign method '%s' for test '%s'\n", fullName, testName); diff --git a/test/api/user_data.c b/test/api/user_data.c new file mode 100644 index 00000000..5532d422 --- /dev/null +++ b/test/api/user_data.c @@ -0,0 +1,51 @@ +#include + +#include "user_data.h" + +static const char* data = "my user data"; +static const char* otherData = "other user data"; + +static void test(WrenVM* vm) +{ + WrenConfiguration configuration; + wrenInitConfiguration(&configuration); + + // Should default to NULL. + if (configuration.userData != NULL) + { + wrenSetSlotBool(vm, 0, false); + return; + } + + configuration.userData = (void*)data; + + WrenVM* otherVM = wrenNewVM(&configuration); + + // Should be able to get it. + if (wrenGetUserData(otherVM) != data) + { + wrenSetSlotBool(vm, 0, false); + wrenFreeVM(otherVM); + return; + } + + // Should be able to set it. + wrenSetUserData(otherVM, (void*)otherData); + + if (wrenGetUserData(otherVM) != otherData) + { + wrenSetSlotBool(vm, 0, false); + wrenFreeVM(otherVM); + return; + } + + wrenSetSlotBool(vm, 0, true); + wrenFreeVM(otherVM); +} + +WrenForeignMethodFn userDataBindMethod(const char* signature) +{ + if (strcmp(signature, "static UserData.test") == 0) return test; + + return NULL; +} diff --git a/test/api/user_data.h b/test/api/user_data.h new file mode 100644 index 00000000..5e195e2b --- /dev/null +++ b/test/api/user_data.h @@ -0,0 +1,3 @@ +#include "wren.h" + +WrenForeignMethodFn userDataBindMethod(const char* signature); diff --git a/test/api/user_data.wren b/test/api/user_data.wren new file mode 100644 index 00000000..0bf00fea --- /dev/null +++ b/test/api/user_data.wren @@ -0,0 +1,5 @@ +class UserData { + foreign static test +} + +System.print(UserData.test) // expect: true diff --git a/util/xcode/wren.xcodeproj/project.pbxproj b/util/xcode/wren.xcodeproj/project.pbxproj index d82494c8..0da22634 100644 --- a/util/xcode/wren.xcodeproj/project.pbxproj +++ b/util/xcode/wren.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ 29D025E41C19CD1000A3BB28 /* os.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E01C19CD1000A3BB28 /* os.c */; }; 29D025E51C19CD1000A3BB28 /* os.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* os.wren.inc */; }; 29D025E61C19CD1000A3BB28 /* os.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* os.wren.inc */; }; + 29D24DB21E82C0A2006618CC /* user_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D24DB01E82C0A2006618CC /* user_data.c */; }; 29D880661DC8ECF600025364 /* reset_stack_after_call_abort.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D880641DC8ECF600025364 /* reset_stack_after_call_abort.c */; }; 29DC149F1BBA2FCC008A8274 /* vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29C8A9311AB71FFF00DEC81D /* vm.c */; }; 29DC14A01BBA2FD6008A8274 /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 2901D7621B74F4050083A2C8 /* timer.c */; }; @@ -152,6 +153,8 @@ 29D025E01C19CD1000A3BB28 /* os.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = os.c; path = ../../src/module/os.c; sourceTree = ""; }; 29D025E11C19CD1000A3BB28 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../../src/module/os.h; sourceTree = ""; }; 29D025E21C19CD1000A3BB28 /* os.wren.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = os.wren.inc; path = ../../src/module/os.wren.inc; sourceTree = ""; }; + 29D24DB01E82C0A2006618CC /* user_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = user_data.c; path = ../../test/api/user_data.c; sourceTree = ""; }; + 29D24DB11E82C0A2006618CC /* user_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = user_data.h; path = ../../test/api/user_data.h; sourceTree = ""; }; 29D880641DC8ECF600025364 /* reset_stack_after_call_abort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = reset_stack_after_call_abort.c; path = ../../test/api/reset_stack_after_call_abort.c; sourceTree = ""; }; 29D880651DC8ECF600025364 /* reset_stack_after_call_abort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reset_stack_after_call_abort.h; path = ../../test/api/reset_stack_after_call_abort.h; sourceTree = ""; }; 29F384111BD19706002F84E0 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io.h; path = ../../src/module/io.h; sourceTree = ""; }; @@ -303,6 +306,8 @@ 29C80D591D73332A00493837 /* reset_stack_after_foreign_construct.h */, 29D009AA1B7E39A8000CE58C /* slots.c */, 29D009AB1B7E39A8000CE58C /* slots.h */, + 29D24DB01E82C0A2006618CC /* user_data.c */, + 29D24DB11E82C0A2006618CC /* user_data.h */, ); name = api_test; sourceTree = ""; @@ -427,6 +432,7 @@ 29DC14A21BBA300A008A8274 /* wren_compiler.c in Sources */, 29DC14A31BBA300D008A8274 /* wren_core.c in Sources */, 29DC14A41BBA3010008A8274 /* wren_debug.c in Sources */, + 29D24DB21E82C0A2006618CC /* user_data.c in Sources */, 29DC14A61BBA3017008A8274 /* wren_primitive.c in Sources */, 29DC14A71BBA301A008A8274 /* wren_utils.c in Sources */, 29DC14A81BBA301D008A8274 /* wren_value.c in Sources */,