Don't pass fiber explicitly to primitives.

Thanks, Michel!
This commit is contained in:
Bob Nystrom
2015-10-02 07:51:12 -07:00
parent b7ed774da3
commit d61d7fd5b4
5 changed files with 17 additions and 14 deletions

View File

@ -133,7 +133,7 @@ DEF_PRIMITIVE(fiber_call1)
DEF_PRIMITIVE(fiber_current)
{
RETURN_OBJ(fiber);
RETURN_OBJ(vm->fiber);
}
DEF_PRIMITIVE(fiber_error)
@ -174,6 +174,7 @@ DEF_PRIMITIVE(fiber_transferError)
DEF_PRIMITIVE(fiber_try)
{
ObjFiber* current = vm->fiber;
ObjFiber* tried = AS_FIBER(args[0]);
// TODO: Use runFiber().
if (tried->numFrames == 0) RETURN_ERROR("Cannot try a finished fiber.");
@ -182,7 +183,7 @@ DEF_PRIMITIVE(fiber_try)
vm->fiber = tried;
// Remember who ran it.
vm->fiber->caller = fiber;
vm->fiber->caller = current;
vm->fiber->callerIsTrying = true;
// If the fiber was yielded, make the yield call return null.
@ -196,11 +197,12 @@ DEF_PRIMITIVE(fiber_try)
DEF_PRIMITIVE(fiber_yield)
{
vm->fiber = fiber->caller;
ObjFiber* current = vm->fiber;
vm->fiber = current->caller;
// Unhook this fiber from the one that called it.
fiber->caller = NULL;
fiber->callerIsTrying = false;
current->caller = NULL;
current->callerIsTrying = false;
if (vm->fiber != NULL)
{
@ -213,11 +215,12 @@ DEF_PRIMITIVE(fiber_yield)
DEF_PRIMITIVE(fiber_yield1)
{
vm->fiber = fiber->caller;
ObjFiber* current = vm->fiber;
vm->fiber = current->caller;
// Unhook this fiber from the one that called it.
fiber->caller = NULL;
fiber->callerIsTrying = false;
current->caller = NULL;
current->callerIsTrying = false;
if (vm->fiber != NULL)
{
@ -228,7 +231,7 @@ DEF_PRIMITIVE(fiber_yield1)
// call in its stack. Since Fiber.yield(value) has two arguments (the Fiber
// class and the value) and we only need one slot for the result, discard
// the other slot now.
fiber->stackTop--;
current->stackTop--;
}
return PRIM_FIBER;

View File

@ -13,7 +13,7 @@ DEF_PRIMITIVE(meta_eval)
if (!validateString(vm, args[1], "Source code")) return PRIM_FIBER;
// Eval the code in the module where the calling function was defined.
Value callingFn = OBJ_VAL(fiber->frames[fiber->numFrames - 1].fn);
Value callingFn = OBJ_VAL(vm->fiber->frames[vm->fiber->numFrames - 1].fn);
ObjModule* module = IS_FN(callingFn)
? AS_FN(callingFn)->module
: AS_CLOSURE(callingFn)->fn->module;
@ -30,7 +30,7 @@ DEF_PRIMITIVE(meta_eval)
ObjFiber* evalFiber = wrenNewFiber(vm, (Obj*)fn);
// Remember what fiber to return to.
evalFiber->caller = fiber;
evalFiber->caller = vm->fiber;
// Switch to the fiber.
vm->fiber = evalFiber;

View File

@ -19,7 +19,7 @@
// the actual type signature of a primitive function and makes it clear which C
// functions are invoked as primitives.
#define DEF_PRIMITIVE(name) \
static PrimitiveResult prim_##name(WrenVM* vm, ObjFiber* fiber, Value* args)
static PrimitiveResult prim_##name(WrenVM* vm, Value* args)
#define RETURN_VAL(value) do { args[0] = value; return PRIM_VALUE; } while (0)

View File

@ -260,7 +260,7 @@ typedef enum
} PrimitiveResult;
typedef PrimitiveResult (*Primitive)(WrenVM* vm, ObjFiber* fiber, Value* args);
typedef PrimitiveResult (*Primitive)(WrenVM* vm, Value* args);
// TODO: See if it's actually a perf improvement to have this in a separate
// struct instead of in ObjFn.

View File

@ -897,7 +897,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
case METHOD_PRIMITIVE:
{
// After calling this, the result will be in the first arg slot.
switch (method->fn.primitive(vm, fiber, args))
switch (method->fn.primitive(vm, args))
{
case PRIM_VALUE:
// The result is now in the first arg slot. Discard the other