"Auxiliary" -> "optional".

Fixes #309.
This commit is contained in:
Bob Nystrom
2015-10-24 09:23:25 -07:00
parent 545a4cbf7e
commit f145662158
14 changed files with 152 additions and 152 deletions
+7 -7
View File
@@ -44,15 +44,15 @@
#endif
#endif
// The VM includes a number of optional "auxiliary" modules. You can choose to
// include these or not. By default, they are all available. To disable one,
// set the corresponding `WREN_AUX_<name>` define to `0`.
#ifndef WREN_AUX_META
#define WREN_AUX_META 1
// The VM includes a number of optional modules. You can choose to include
// these or not. By default, they are all available. To disable one, set the
// corresponding `WREN_OPT_<name>` define to `0`.
#ifndef WREN_OPT_META
#define WREN_OPT_META 1
#endif
#ifndef WREN_AUX_RANDOM
#define WREN_AUX_RANDOM 1
#ifndef WREN_OPT_RANDOM
#define WREN_OPT_RANDOM 1
#endif
// These flags are useful for debugging and hacking on Wren itself. They are not
+68 -68
View File
@@ -8,11 +8,11 @@
#include "wren_debug.h"
#include "wren_vm.h"
#if WREN_AUX_META
#include "wren_aux_meta.h"
#if WREN_OPT_META
#include "wren_opt_meta.h"
#endif
#if WREN_AUX_RANDOM
#include "wren_aux_random.h"
#if WREN_OPT_RANDOM
#include "wren_opt_random.h"
#endif
#if WREN_DEBUG_TRACE_MEMORY || WREN_DEBUG_TRACE_GC
@@ -59,15 +59,15 @@ WrenVM* wrenNewVM(WrenConfiguration* config)
vm->modules = wrenNewMap(vm);
wrenInitializeCore(vm);
// TODO: Lazy load these.
#if WREN_AUX_META
#if WREN_OPT_META
wrenLoadMetaModule(vm);
#endif
#if WREN_AUX_RANDOM
#if WREN_OPT_RANDOM
wrenLoadRandomModule(vm);
#endif
return vm;
}
@@ -88,7 +88,7 @@ void wrenFreeVM(WrenVM* vm)
// 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.");
wrenSymbolTableClear(vm, &vm->methodNames);
DEALLOCATE(vm, vm);
@@ -261,11 +261,11 @@ static void closeUpvalues(ObjFiber* fiber, Value* last)
fiber->openUpvalues->value >= last)
{
ObjUpvalue* upvalue = fiber->openUpvalues;
// Move the value into the upvalue itself and point the upvalue to it.
upvalue->closed = *upvalue->value;
upvalue->value = &upvalue->closed;
// Remove it from the open upvalue list.
fiber->openUpvalues = upvalue->next;
}
@@ -358,21 +358,21 @@ static void callForeign(WrenVM* vm, ObjFiber* fiber,
static void runtimeError(WrenVM* vm)
{
ASSERT(!IS_NULL(vm->fiber->error), "Should only call this after an error.");
// Unhook the caller since we will never resume and return to it.
ObjFiber* caller = vm->fiber->caller;
vm->fiber->caller = NULL;
// If the caller ran this fiber using "try", give it the error.
if (vm->fiber->callerIsTrying)
{
// Make the caller's try method return the error message.
caller->stackTop[-1] = vm->fiber->error;
vm->fiber = caller;
return;
}
// If we got here, nothing caught the error, so show the stack trace.
wrenDebugPrintStackTrace(vm->fiber);
vm->fiber = NULL;
@@ -403,12 +403,12 @@ static bool checkArity(WrenVM* vm, Value value, int numArgs)
ASSERT(IS_FN(value), "Receiver must be a function or closure.");
fn = AS_FN(value);
}
// We only care about missing arguments, not extras. The "- 1" is because
// numArgs includes the receiver, the function itself, which we don't want to
// count.
if (numArgs - 1 >= fn->arity) return true;
vm->fiber->error = CONST_STRING(vm, "Function expects more arguments.");
return false;
}
@@ -427,7 +427,7 @@ static inline void callFunction(
sizeof(CallFrame) * max);
fiber->frameCapacity = max;
}
// TODO: Check for stack overflow. We handle the call frame array growing,
// but not the stack itself.
@@ -561,7 +561,7 @@ static Value validateSuperclass(WrenVM* vm, Value name, Value superclassValue,
"Class '@' cannot inherit from built-in class '@'.",
name, OBJ_VAL(superclass->name));
}
if (superclass->numFields == -1)
{
return wrenStringFormat(vm,
@@ -575,7 +575,7 @@ static Value validateSuperclass(WrenVM* vm, Value name, Value superclassValue,
"Foreign class '@' may not inherit from a class with fields.",
name);
}
if (superclass->numFields + numFields > MAX_FIELDS)
{
return wrenStringFormat(vm,
@@ -591,24 +591,24 @@ static void bindForeignClass(WrenVM* vm, ObjClass* classObj, ObjModule* module)
// TODO: Make this a runtime error?
ASSERT(vm->config.bindForeignClassFn != NULL,
"Cannot declare foreign classes without a bindForeignClassFn.");
WrenForeignClassMethods methods = vm->config.bindForeignClassFn(
vm, module->name->value, classObj->name->value);
Method method;
method.type = METHOD_FOREIGN;
method.fn.foreign = methods.allocate;
ASSERT(method.fn.foreign != NULL,
"A foreign class must provide an allocate function.");
int symbol = wrenSymbolTableEnsure(vm, &vm->methodNames, "<allocate>", 10);
wrenBindMethod(vm, classObj, symbol, method);
// Add the symbol even if there is no finalizer so we can ensure that the
// symbol itself is always in the symbol table.
symbol = wrenSymbolTableEnsure(vm, &vm->methodNames, "<finalize>", 10);
if (methods.finalize != NULL)
{
method.fn.foreign = methods.finalize;
@@ -628,18 +628,18 @@ static void createClass(WrenVM* vm, int numFields, ObjModule* module)
// Pull the name and superclass off the stack.
Value name = vm->fiber->stackTop[-2];
Value superclass = vm->fiber->stackTop[-1];
// We have two values on the stack and we are going to leave one, so discard
// the other slot.
vm->fiber->stackTop--;
vm->fiber->error = validateSuperclass(vm, name, superclass, numFields);
if (!IS_NULL(vm->fiber->error)) return;
ObjClass* classObj = wrenNewClass(vm, AS_CLASS(superclass), numFields,
AS_STRING(name));
vm->fiber->stackTop[-1] = OBJ_VAL(classObj);
if (numFields == -1) bindForeignClass(vm, classObj, module);
}
@@ -647,21 +647,21 @@ static void createForeign(WrenVM* vm, ObjFiber* fiber, Value* stack)
{
ObjClass* classObj = AS_CLASS(stack[0]);
ASSERT(classObj->numFields == -1, "Class must be a foreign class.");
// TODO: Don't look up every time.
int symbol = wrenSymbolTableFind(&vm->methodNames, "<allocate>", 10);
ASSERT(symbol != -1, "Should have defined <allocate> symbol.");
ASSERT(classObj->methods.count > symbol, "Class should have allocator.");
Method* method = &classObj->methods.data[symbol];
ASSERT(method->type == METHOD_FOREIGN, "Allocator should be foreign.");
// Pass the constructor arguments to the allocator as well.
vm->foreignCallSlot = stack;
vm->foreignCallNumArgs = (int)(fiber->stackTop - stack);
method->fn.foreign(vm);
// TODO: Check that allocateForeign was called.
}
@@ -670,24 +670,24 @@ void wrenFinalizeForeign(WrenVM* vm, ObjForeign* foreign)
// TODO: Don't look up every time.
int symbol = wrenSymbolTableFind(&vm->methodNames, "<finalize>", 10);
ASSERT(symbol != -1, "Should have defined <finalize> symbol.");
// If there are no finalizers, don't finalize it.
if (symbol == -1) return;
// If the class doesn't have a finalizer, bail out.
ObjClass* classObj = foreign->obj.classObj;
if (symbol >= classObj->methods.count) return;
Method* method = &classObj->methods.data[symbol];
if (method->type == METHOD_NONE) return;
ASSERT(method->type == METHOD_FOREIGN, "Finalizer should be foreign.");
// Pass the constructor arguments to the allocator as well.
Value slot = OBJ_VAL(foreign);
vm->foreignCallSlot = &slot;
vm->foreignCallNumArgs = 1;
method->fn.foreign(vm);
}
@@ -941,7 +941,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
case METHOD_FOREIGN:
callForeign(vm, fiber, method->fn.foreign, numArgs);
break;
case METHOD_FN_CALL:
if (!checkArity(vm, args[0], numArgs)) RUNTIME_ERROR();
@@ -1091,7 +1091,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
// Close any upvalues still in scope.
closeUpvalues(fiber, stackStart);
// If the fiber is complete, end it.
if (fiber->numFrames == 0)
{
@@ -1101,7 +1101,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
// We have a calling fiber to resume.
ObjFiber* callingFiber = fiber->caller;
fiber->caller = NULL;
fiber = callingFiber;
vm->fiber = fiber;
@@ -1127,7 +1127,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
ASSERT(IS_CLASS(stackStart[0]), "'this' should be a class.");
stackStart[0] = wrenNewInstance(vm, AS_CLASS(stackStart[0]));
DISPATCH();
CASE_CODE(FOREIGN_CONSTRUCT):
ASSERT(IS_CLASS(stackStart[0]), "'this' should be a class.");
createForeign(vm, fiber, stackStart);
@@ -1172,14 +1172,14 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
if (!IS_NULL(fiber->error)) RUNTIME_ERROR();
DISPATCH();
}
CASE_CODE(FOREIGN_CLASS):
{
createClass(vm, -1, fn->module);
if (!IS_NULL(fiber->error)) RUNTIME_ERROR();
DISPATCH();
}
CASE_CODE(METHOD_INSTANCE):
CASE_CODE(METHOD_STATIC):
{
@@ -1321,7 +1321,7 @@ WrenInterpretResult wrenCall(WrenVM* vm, WrenValue* method,
WrenInterpretResult result = wrenCallVarArgs(vm, method, returnValue,
argTypes, args);
va_end(args);
return result;
}
@@ -1331,10 +1331,10 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
{
// TODO: Validate that the number of arguments matches what the method
// expects.
ASSERT(IS_FIBER(method->value), "Value must come from wrenGetMethod().");
ObjFiber* fiber = AS_FIBER(method->value);
// Push the arguments.
for (const char* argType = argTypes; *argType != '\0'; argType++)
{
@@ -1348,7 +1348,7 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
value = wrenNewString(vm, bytes, (size_t)length);
break;
}
case 'b': value = BOOL_VAL(va_arg(args, int)); break;
case 'd': value = NUM_VAL(va_arg(args, double)); break;
case 'i': value = NUM_VAL((double)va_arg(args, int)); break;
@@ -1356,7 +1356,7 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
case 's':
value = wrenStringFormat(vm, "$", va_arg(args, const char*));
break;
case 'v':
{
// Allow a NULL value pointer for Wren null.
@@ -1364,21 +1364,21 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
if (wrenValue != NULL) value = wrenValue->value;
break;
}
default:
ASSERT(false, "Unknown argument type.");
break;
}
*fiber->stackTop++ = value;
}
Value receiver = fiber->stack[0];
Obj* fn = fiber->frames[0].fn;
wrenPushRoot(vm, (Obj*)fn);
WrenInterpretResult result = runInterpreter(vm, fiber);
if (result == WREN_RESULT_SUCCESS)
{
if (returnValue != NULL)
@@ -1387,10 +1387,10 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
fiber->stackTop++;
*returnValue = wrenCaptureValue(vm, fiber->stack[0]);
}
// Reset the fiber to get ready for the next call.
wrenResetFiber(vm, fiber, fn);
// Push the receiver back on the stack.
*fiber->stackTop++ = receiver;
}
@@ -1398,9 +1398,9 @@ WrenInterpretResult wrenCallVarArgs(WrenVM* vm, WrenValue* method,
{
if (returnValue != NULL) *returnValue = NULL;
}
wrenPopRoot(vm);
return result;
}
@@ -1422,14 +1422,14 @@ WrenValue* wrenCaptureValue(WrenVM* vm, Value value)
void wrenReleaseValue(WrenVM* vm, WrenValue* value)
{
ASSERT(value != NULL, "NULL value.");
// Update the VM's head pointer if we're releasing the first handle.
if (vm->valueHandles == value) vm->valueHandles = value->next;
// Unlink it from the list.
if (value->prev != NULL) value->prev->next = value->next;
if (value->next != NULL) value->next->prev = value->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;
@@ -1448,7 +1448,7 @@ void* wrenAllocateForeign(WrenVM* vm, size_t size)
ObjForeign* foreign = wrenNewForeign(vm, classObj, size);
vm->foreignCallSlot[0] = OBJ_VAL(foreign);
return (void*)foreign->data;
}
@@ -1466,7 +1466,7 @@ WrenInterpretResult wrenInterpretInModule(WrenVM* vm, const char* module,
nameValue = wrenStringFormat(vm, "$", module);
wrenPushRoot(vm, AS_OBJ(nameValue));
}
ObjFiber* fiber = loadModule(vm, nameValue, source);
if (fiber == NULL)
{
@@ -1608,9 +1608,9 @@ double wrenGetArgumentDouble(WrenVM* vm, int index)
void* wrenGetArgumentForeign(WrenVM* vm, int index)
{
validateForeignArgument(vm, index);
if (!IS_FOREIGN(*(vm->foreignCallSlot + index))) return NULL;
return AS_FOREIGN(*(vm->foreignCallSlot + index))->data;
}
@@ -1662,7 +1662,7 @@ void wrenReturnValue(WrenVM* vm, WrenValue* value)
{
ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call.");
ASSERT(value != NULL, "Value cannot be NULL.");
*vm->foreignCallSlot = value->value;
vm->foreignCallSlot = NULL;
}