Unify PRIM_ERROR and PRIM_RUN_FIBER.

This commit is contained in:
Bob Nystrom
2015-09-30 07:32:39 -07:00
parent b05a74da19
commit 5129597c63
5 changed files with 53 additions and 58 deletions

View File

@ -50,7 +50,7 @@ DEF_PRIMITIVE(class_toString)
DEF_PRIMITIVE(fiber_new)
{
if (!validateFn(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateFn(vm, args[1], "Argument")) return PRIM_FIBER;
ObjFiber* newFiber = wrenNewFiber(vm, AS_OBJ(args[1]));
@ -70,7 +70,7 @@ DEF_PRIMITIVE(fiber_abort)
vm->fiber->error = args[1];
// If the error is explicitly null, it's not really an abort.
return IS_NULL(args[1]) ? PRIM_VALUE : PRIM_ERROR;
return IS_NULL(args[1]) ? PRIM_VALUE : PRIM_FIBER;
}
// Transfer execution to [fiber] coming from the current fiber whose stack has
@ -95,14 +95,14 @@ static PrimitiveResult runFiber(WrenVM* vm, ObjFiber* fiber, Value* args,
{
vm->fiber->error = wrenStringFormat(vm, "Cannot $ a finished fiber.",
isCall ? "call" : "transfer to");
return PRIM_ERROR;
return PRIM_FIBER;
}
if (!IS_NULL(fiber->error))
{
vm->fiber->error = wrenStringFormat(vm, "Cannot $ an aborted fiber.",
isCall ? "call" : "transfer to");
return PRIM_ERROR;
return PRIM_FIBER;
}
// When the calling fiber resumes, we'll store the result of the call in its
@ -118,7 +118,7 @@ static PrimitiveResult runFiber(WrenVM* vm, ObjFiber* fiber, Value* args,
vm->fiber = fiber;
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
DEF_PRIMITIVE(fiber_call)
@ -151,7 +151,7 @@ DEF_PRIMITIVE(fiber_suspend)
{
// Switching to a null fiber tells the interpreter to stop and exit.
vm->fiber = NULL;
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
DEF_PRIMITIVE(fiber_transfer)
@ -167,7 +167,7 @@ DEF_PRIMITIVE(fiber_transfer1)
DEF_PRIMITIVE(fiber_transferError)
{
PrimitiveResult result = runFiber(vm, AS_FIBER(args[0]), args, false, true);
if (result == PRIM_RUN_FIBER) vm->fiber->error = args[1];
if (result == PRIM_FIBER) vm->fiber->error = args[1];
return result;
}
@ -191,7 +191,7 @@ DEF_PRIMITIVE(fiber_try)
vm->fiber->stackTop[-1] = NULL_VAL;
}
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
DEF_PRIMITIVE(fiber_yield)
@ -208,7 +208,7 @@ DEF_PRIMITIVE(fiber_yield)
vm->fiber->stackTop[-1] = NULL_VAL;
}
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
DEF_PRIMITIVE(fiber_yield1)
@ -231,12 +231,12 @@ DEF_PRIMITIVE(fiber_yield1)
fiber->stackTop--;
}
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
DEF_PRIMITIVE(fn_new)
{
if (!validateFn(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateFn(vm, args[1], "Argument")) return PRIM_FIBER;
// The block argument is already a function, so just return it.
RETURN_VAL(args[1]);
@ -316,7 +316,7 @@ DEF_PRIMITIVE(list_insert)
// count + 1 here so you can "insert" at the very end.
uint32_t index = validateIndex(vm, args[1], list->elements.count + 1,
"Index");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
wrenListInsert(vm, list, args[2], index);
RETURN_VAL(args[2]);
@ -333,7 +333,7 @@ DEF_PRIMITIVE(list_iterate)
RETURN_NUM(0);
}
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
// Stop if we're out of bounds.
double index = AS_NUM(args[1]);
@ -347,7 +347,7 @@ DEF_PRIMITIVE(list_iteratorValue)
{
ObjList* list = AS_LIST(args[0]);
uint32_t index = validateIndex(vm, args[1], list->elements.count, "Iterator");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
RETURN_VAL(list->elements.data[index]);
}
@ -356,7 +356,7 @@ DEF_PRIMITIVE(list_removeAt)
{
ObjList* list = AS_LIST(args[0]);
uint32_t index = validateIndex(vm, args[1], list->elements.count, "Index");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
RETURN_VAL(wrenListRemoveAt(vm, list, index));
}
@ -369,7 +369,7 @@ DEF_PRIMITIVE(list_subscript)
{
uint32_t index = validateIndex(vm, args[1], list->elements.count,
"Subscript");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
RETURN_VAL(list->elements.data[index]);
}
@ -382,7 +382,7 @@ DEF_PRIMITIVE(list_subscript)
int step;
uint32_t count = list->elements.count;
uint32_t start = calculateRange(vm, AS_RANGE(args[1]), &count, &step);
if (start == UINT32_MAX) return PRIM_ERROR;
if (start == UINT32_MAX) return PRIM_FIBER;
ObjList* result = wrenNewList(vm, count);
for (uint32_t i = 0; i < count; i++)
@ -398,7 +398,7 @@ DEF_PRIMITIVE(list_subscriptSetter)
ObjList* list = AS_LIST(args[0]);
uint32_t index = validateIndex(vm, args[1], list->elements.count,
"Subscript");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
list->elements.data[index] = args[2];
RETURN_VAL(args[2]);
@ -411,7 +411,7 @@ DEF_PRIMITIVE(map_new)
DEF_PRIMITIVE(map_subscript)
{
if (!validateKey(vm, args[1])) return PRIM_ERROR;
if (!validateKey(vm, args[1])) return PRIM_FIBER;
ObjMap* map = AS_MAP(args[0]);
Value value = wrenMapGet(map, args[1]);
@ -422,7 +422,7 @@ DEF_PRIMITIVE(map_subscript)
DEF_PRIMITIVE(map_subscriptSetter)
{
if (!validateKey(vm, args[1])) return PRIM_ERROR;
if (!validateKey(vm, args[1])) return PRIM_FIBER;
wrenMapSet(vm, AS_MAP(args[0]), args[1], args[2]);
RETURN_VAL(args[2]);
@ -436,7 +436,7 @@ DEF_PRIMITIVE(map_clear)
DEF_PRIMITIVE(map_containsKey)
{
if (!validateKey(vm, args[1])) return PRIM_ERROR;
if (!validateKey(vm, args[1])) return PRIM_FIBER;
RETURN_BOOL(!IS_UNDEFINED(wrenMapGet(AS_MAP(args[0]), args[1])));
}
@ -458,7 +458,7 @@ DEF_PRIMITIVE(map_iterate)
// Otherwise, start one past the last entry we stopped at.
if (!IS_NULL(args[1]))
{
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
index = (uint32_t)AS_NUM(args[1]);
@ -481,7 +481,7 @@ DEF_PRIMITIVE(map_iterate)
DEF_PRIMITIVE(map_remove)
{
if (!validateKey(vm, args[1])) return PRIM_ERROR;
if (!validateKey(vm, args[1])) return PRIM_FIBER;
RETURN_VAL(wrenMapRemoveKey(vm, AS_MAP(args[0]), args[1]));
}
@ -490,7 +490,7 @@ DEF_PRIMITIVE(map_keyIteratorValue)
{
ObjMap* map = AS_MAP(args[0]);
uint32_t index = validateIndex(vm, args[1], map->capacity, "Iterator");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
MapEntry* entry = &map->entries[index];
if (IS_UNDEFINED(entry->key))
@ -505,7 +505,7 @@ DEF_PRIMITIVE(map_valueIteratorValue)
{
ObjMap* map = AS_MAP(args[0]);
uint32_t index = validateIndex(vm, args[1], map->capacity, "Iterator");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
MapEntry* entry = &map->entries[index];
if (IS_UNDEFINED(entry->key))
@ -528,7 +528,7 @@ DEF_PRIMITIVE(null_toString)
DEF_PRIMITIVE(num_fromString)
{
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
ObjString* string = AS_STRING(args[1]);
@ -545,7 +545,7 @@ DEF_PRIMITIVE(num_fromString)
if (errno == ERANGE)
{
vm->fiber->error = CONST_STRING(vm, "Number literal is too large.");
return PRIM_ERROR;
return PRIM_FIBER;
}
// We must have consumed the entire string. Otherwise, it contains non-number
@ -564,7 +564,7 @@ DEF_PRIMITIVE(num_pi)
#define DEF_NUM_INFIX(name, op, type) \
DEF_PRIMITIVE(num_##name) \
{ \
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR; \
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER; \
RETURN_##type(AS_NUM(args[0]) op AS_NUM(args[1])); \
}
@ -581,7 +581,7 @@ DEF_NUM_INFIX(gte, >=, BOOL)
#define DEF_NUM_BITWISE(name, op) \
DEF_PRIMITIVE(num_bitwise##name) \
{ \
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR; \
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER; \
uint32_t left = (uint32_t)AS_NUM(args[0]); \
uint32_t right = (uint32_t)AS_NUM(args[1]); \
RETURN_NUM(left op right); \
@ -614,7 +614,7 @@ DEF_NUM_FN(tan, tan)
DEF_PRIMITIVE(num_mod)
{
if (!validateNum(vm, args[1], "Right operand")) return PRIM_ERROR;
if (!validateNum(vm, args[1], "Right operand")) return PRIM_FIBER;
RETURN_NUM(fmod(AS_NUM(args[0]), AS_NUM(args[1])));
}
@ -638,7 +638,7 @@ DEF_PRIMITIVE(num_bitwiseNot)
DEF_PRIMITIVE(num_dotDot)
{
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_ERROR;
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_FIBER;
double from = AS_NUM(args[0]);
double to = AS_NUM(args[1]);
@ -647,7 +647,7 @@ DEF_PRIMITIVE(num_dotDot)
DEF_PRIMITIVE(num_dotDotDot)
{
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_ERROR;
if (!validateNum(vm, args[1], "Right hand side of range")) return PRIM_FIBER;
double from = AS_NUM(args[0]);
double to = AS_NUM(args[1]);
@ -790,7 +790,7 @@ DEF_PRIMITIVE(range_iterate)
// Start the iteration.
if (IS_NULL(args[1])) RETURN_NUM(range->from);
if (!validateNum(vm, args[1], "Iterator")) return PRIM_ERROR;
if (!validateNum(vm, args[1], "Iterator")) return PRIM_FIBER;
double iterator = AS_NUM(args[1]);
@ -837,7 +837,7 @@ DEF_PRIMITIVE(range_toString)
DEF_PRIMITIVE(string_fromCodePoint)
{
if (!validateInt(vm, args[1], "Code point")) return PRIM_ERROR;
if (!validateInt(vm, args[1], "Code point")) return PRIM_FIBER;
int codePoint = (int)AS_NUM(args[1]);
if (codePoint < 0)
@ -857,7 +857,7 @@ DEF_PRIMITIVE(string_byteAt)
ObjString* string = AS_STRING(args[0]);
uint32_t index = validateIndex(vm, args[1], string->length, "Index");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
RETURN_NUM((uint8_t)string->value[index]);
}
@ -872,7 +872,7 @@ DEF_PRIMITIVE(string_codePointAt)
ObjString* string = AS_STRING(args[0]);
uint32_t index = validateIndex(vm, args[1], string->length, "Index");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
// If we are in the middle of a UTF-8 sequence, indicate that.
const uint8_t* bytes = (uint8_t*)string->value;
@ -885,7 +885,7 @@ DEF_PRIMITIVE(string_codePointAt)
DEF_PRIMITIVE(string_contains)
{
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
ObjString* string = AS_STRING(args[0]);
ObjString* search = AS_STRING(args[1]);
@ -895,7 +895,7 @@ DEF_PRIMITIVE(string_contains)
DEF_PRIMITIVE(string_endsWith)
{
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
ObjString* string = AS_STRING(args[0]);
ObjString* search = AS_STRING(args[1]);
@ -909,7 +909,7 @@ DEF_PRIMITIVE(string_endsWith)
DEF_PRIMITIVE(string_indexOf)
{
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
ObjString* string = AS_STRING(args[0]);
ObjString* search = AS_STRING(args[1]);
@ -929,7 +929,7 @@ DEF_PRIMITIVE(string_iterate)
RETURN_NUM(0);
}
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
uint32_t index = (uint32_t)AS_NUM(args[1]);
@ -955,7 +955,7 @@ DEF_PRIMITIVE(string_iterateByte)
RETURN_NUM(0);
}
if (!validateInt(vm, args[1], "Iterator")) return PRIM_ERROR;
if (!validateInt(vm, args[1], "Iterator")) return PRIM_FIBER;
if (AS_NUM(args[1]) < 0) RETURN_FALSE;
uint32_t index = (uint32_t)AS_NUM(args[1]);
@ -971,14 +971,14 @@ DEF_PRIMITIVE(string_iteratorValue)
{
ObjString* string = AS_STRING(args[0]);
uint32_t index = validateIndex(vm, args[1], string->length, "Iterator");
if (index == UINT32_MAX) return PRIM_ERROR;
if (index == UINT32_MAX) return PRIM_FIBER;
RETURN_VAL(wrenStringCodePointAt(vm, string, index));
}
DEF_PRIMITIVE(string_startsWith)
{
if (!validateString(vm, args[1], "Argument")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Argument")) return PRIM_FIBER;
ObjString* string = AS_STRING(args[0]);
ObjString* search = AS_STRING(args[1]);
@ -991,7 +991,7 @@ DEF_PRIMITIVE(string_startsWith)
DEF_PRIMITIVE(string_plus)
{
if (!validateString(vm, args[1], "Right operand")) return PRIM_ERROR;
if (!validateString(vm, args[1], "Right operand")) return PRIM_FIBER;
RETURN_VAL(wrenStringFormat(vm, "@@", args[0], args[1]));
}
@ -1002,7 +1002,7 @@ DEF_PRIMITIVE(string_subscript)
if (IS_NUM(args[1]))
{
int index = validateIndex(vm, args[1], string->length, "Subscript");
if (index == -1) return PRIM_ERROR;
if (index == -1) return PRIM_FIBER;
RETURN_VAL(wrenStringCodePointAt(vm, string, index));
}
@ -1015,7 +1015,7 @@ DEF_PRIMITIVE(string_subscript)
int step;
uint32_t count = string->length;
int start = calculateRange(vm, AS_RANGE(args[1]), &count, &step);
if (start == -1) return PRIM_ERROR;
if (start == -1) return PRIM_FIBER;
RETURN_VAL(wrenNewStringFromRange(vm, string, start, count, step));
}

View File

@ -10,7 +10,7 @@
DEF_PRIMITIVE(meta_eval)
{
if (!validateString(vm, args[1], "Source code")) return PRIM_ERROR;
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);
@ -36,7 +36,7 @@ DEF_PRIMITIVE(meta_eval)
vm->fiber = evalFiber;
wrenPopRoot(vm);
return PRIM_RUN_FIBER;
return PRIM_FIBER;
}
void wrenLoadMetaLibrary(WrenVM* vm)

View File

@ -33,7 +33,7 @@
#define RETURN_ERROR(msg) \
do { \
vm->fiber->error = wrenStringFormat(vm, "$", msg); \
return PRIM_ERROR; \
return PRIM_FIBER; \
} while (0);
// Validates that the given [arg] is a function. Returns true if it is. If not,

View File

@ -251,14 +251,12 @@ typedef enum
// A normal value has been returned.
PRIM_VALUE,
// A runtime error occurred.
PRIM_ERROR,
// A new callframe has been pushed.
PRIM_CALL,
// A fiber is being switched to.
PRIM_RUN_FIBER
// A fiber is being switched to. Also used for runtime errors (which also
// change which fiber is being executed).
PRIM_FIBER
} PrimitiveResult;

View File

@ -905,16 +905,13 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
fiber->stackTop -= numArgs - 1;
break;
case PRIM_ERROR:
RUNTIME_ERROR();
case PRIM_CALL:
STORE_FRAME();
callFunction(vm, fiber, AS_OBJ(args[0]), numArgs);
LOAD_FRAME();
break;
case PRIM_RUN_FIBER:
case PRIM_FIBER:
STORE_FRAME();
// If we don't have a fiber to switch to, stop interpreting.