From 56d4d3e671c26587336bbee2cb1b659880678140 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Fri, 7 Aug 2015 07:57:23 -0700 Subject: [PATCH] Allow passing WrenValues to wrenCall(). --- src/include/wren.h | 2 ++ src/vm/wren_vm.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/include/wren.h b/src/include/wren.h index 7792b22d..d08d9d0a 100644 --- a/src/include/wren.h +++ b/src/include/wren.h @@ -174,6 +174,8 @@ WrenMethod* wrenGetMethod(WrenVM* vm, const char* module, const char* variable, // will allocate its own string and copy the characters from this, so // you don't have to worry about the lifetime of the string you pass to // Wren. +// - "v" - A previously acquired WrenValue*. Passing this in does not implicitly +// release the value. void wrenCall(WrenVM* vm, WrenMethod* method, const char* argTypes, ...); // Releases memory associated with [method]. After calling this, [method] can diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index 5e26d599..eef3a515 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -1170,9 +1170,13 @@ static ObjFn* makeCallStub(WrenVM* vm, ObjModule* module, const char* signature) // Count the number parameters the method expects. int numParams = 0; - for (const char* s = signature; *s != '\0'; s++) + if (signature[signatureLength - 1] == ')') { - if (*s == '_') numParams++; + for (const char* s = signature + signatureLength - 2; + s > signature && *s != '('; s--) + { + if (*s == '_') numParams++; + } } int method = wrenSymbolTableEnsure(vm, &vm->methodNames, @@ -1255,6 +1259,8 @@ void wrenCall(WrenVM* vm, WrenMethod* method, const char* argTypes, ...) value = wrenStringFormat(vm, "$", va_arg(argList, const char*)); break; } + + case 'v': value = va_arg(argList, WrenValue*)->value; break; default: ASSERT(false, "Unknown argument type."); @@ -1266,15 +1272,15 @@ void wrenCall(WrenVM* vm, WrenMethod* method, const char* argTypes, ...) va_end(argList); - Value receiver = method->fiber->stack[0]; + Value receiver = method->fiber->stack[0]; Obj* fn = method->fiber->frames[0].fn; - + // TODO: How does this handle a runtime error occurring? runInterpreter(vm, method->fiber); // Reset the fiber to get ready for the next call. wrenResetFiber(vm, method->fiber, fn); - + // Push the receiver back on the stack. *method->fiber->stackTop++ = receiver; }