Sporadic cleanup

This commit is contained in:
K. Lange 2021-04-06 20:41:31 +09:00
parent 1f76e7a846
commit fa3020143b
2 changed files with 39 additions and 43 deletions

View File

@ -540,7 +540,7 @@ extern KrkClass * krk_getType(KrkValue value);
* @param type Class object to test for membership of. * @param type Class object to test for membership of.
* @return 1 if @p obj is an instance of @p type or of a subclass of @p type * @return 1 if @p obj is an instance of @p type or of a subclass of @p type
*/ */
extern int krk_isInstanceOf(KrkValue obj, KrkClass * type); extern int krk_isInstanceOf(KrkValue obj, const KrkClass * type);
/** /**
* @brief Perform method binding on the stack. * @brief Perform method binding on the stack.
@ -667,7 +667,7 @@ extern void krk_finalizeClass(KrkClass * _class);
* open source files to print faulting lines and may call into the VM if the * open source files to print faulting lines and may call into the VM if the
* exception object has a managed implementation of @c \__str__. * exception object has a managed implementation of @c \__str__.
*/ */
extern void krk_dumpTraceback(); extern void krk_dumpTraceback(void);
/** /**
* @brief Set up a new module object in the current thread. * @brief Set up a new module object in the current thread.

View File

@ -109,7 +109,7 @@ static KrkValue _specialMethodNames[METHOD__MAX];
* clear the exception flag and current exception; * clear the exception flag and current exception;
* happens on startup (twice) and after an exception. * happens on startup (twice) and after an exception.
*/ */
void krk_resetStack() { void krk_resetStack(void) {
krk_currentThread.stackTop = krk_currentThread.stack; krk_currentThread.stackTop = krk_currentThread.stack;
krk_currentThread.frameCount = 0; krk_currentThread.frameCount = 0;
krk_currentThread.openUpvalues = NULL; krk_currentThread.openUpvalues = NULL;
@ -124,7 +124,7 @@ void krk_resetStack() {
* and then move inwards; on each call frame we try to open * and then move inwards; on each call frame we try to open
* the source file and print the corresponding line. * the source file and print the corresponding line.
*/ */
void krk_dumpTraceback() { void krk_dumpTraceback(void) {
if (!krk_valuesEqual(krk_currentThread.currentException,NONE_VAL())) { if (!krk_valuesEqual(krk_currentThread.currentException,NONE_VAL())) {
krk_push(krk_currentThread.currentException); krk_push(krk_currentThread.currentException);
KrkValue tracebackEntries; KrkValue tracebackEntries;
@ -480,7 +480,7 @@ inline KrkClass * krk_getType(KrkValue of) {
* type and didn't inherit from object(), everything is eventually * type and didn't inherit from object(), everything is eventually
* an object - even basic types like INTEGERs and FLOATINGs. * an object - even basic types like INTEGERs and FLOATINGs.
*/ */
int krk_isInstanceOf(KrkValue obj, KrkClass * type) { int krk_isInstanceOf(KrkValue obj, const KrkClass * type) {
KrkClass * mine = krk_getType(obj); KrkClass * mine = krk_getType(obj);
while (mine) { while (mine) {
if (mine == type) return 1; if (mine == type) return 1;
@ -489,7 +489,7 @@ int krk_isInstanceOf(KrkValue obj, KrkClass * type) {
return 0; return 0;
} }
static inline int checkArgumentCount(KrkClosure * closure, int argCount) { static inline int checkArgumentCount(const KrkClosure * closure, int argCount) {
int minArgs = closure->function->requiredArgs; int minArgs = closure->function->requiredArgs;
int maxArgs = minArgs + closure->function->keywordArgs; int maxArgs = minArgs + closure->function->keywordArgs;
if (unlikely(argCount < minArgs || argCount > maxArgs)) { if (unlikely(argCount < minArgs || argCount > maxArgs)) {
@ -504,7 +504,7 @@ static inline int checkArgumentCount(KrkClosure * closure, int argCount) {
return 1; return 1;
} }
static void multipleDefs(KrkClosure * closure, int destination) { static void multipleDefs(const KrkClosure * closure, int destination) {
krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%s'", krk_runtimeError(vm.exceptions->typeError, "%s() got multiple values for argument '%s'",
closure->function->name ? closure->function->name->chars : "<unnamed>", closure->function->name ? closure->function->name->chars : "<unnamed>",
(destination < closure->function->requiredArgs ? AS_CSTRING(closure->function->requiredArgNames.values[destination]) : (destination < closure->function->requiredArgs ? AS_CSTRING(closure->function->requiredArgNames.values[destination]) :
@ -711,37 +711,34 @@ _finishKwarg:
} }
argCountX = argCount - (!!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) + !!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)); argCountX = argCount - (!!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) + !!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS));
} else { } else if ((size_t)argCount > potentialPositionalArgs && (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS)) {
/* We can't have had any kwargs. */ krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop();
if ((size_t)argCount > potentialPositionalArgs && (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS)) { startOfPositionals = &krk_currentThread.stackTop[-argCount];
krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop(); KrkValue tmp = krk_list_of(argCount - potentialPositionalArgs,
startOfPositionals = &krk_currentThread.stackTop[-argCount]; &startOfPositionals[potentialPositionalArgs], 0);
KrkValue tmp = krk_list_of(argCount - potentialPositionalArgs, startOfPositionals = &krk_currentThread.stackTop[-argCount];
&startOfPositionals[potentialPositionalArgs], 0); startOfPositionals[offsetOfExtraArgs] = tmp;
startOfPositionals = &krk_currentThread.stackTop[-argCount]; argCount = closure->function->requiredArgs + 1;
startOfPositionals[offsetOfExtraArgs] = tmp; argCountX = argCount - 1;
argCount = closure->function->requiredArgs + 1; while (krk_currentThread.stackTop > startOfPositionals + argCount) krk_pop();
argCountX = argCount - 1;
while (krk_currentThread.stackTop > startOfPositionals + argCount) krk_pop();
}
}
if (unlikely(!checkArgumentCount(closure, argCountX))) {
return 0;
} }
if (unlikely(!checkArgumentCount(closure, argCountX))) goto _errorAfterKeywords;
while (argCount < (int)totalArguments) { while (argCount < (int)totalArguments) {
krk_push(KWARGS_VAL(0)); krk_push(KWARGS_VAL(0));
argCount++; argCount++;
} }
if (unlikely(closure->function->flags & (KRK_CODEOBJECT_FLAGS_IS_GENERATOR | KRK_CODEOBJECT_FLAGS_IS_COROUTINE))) { if (unlikely(closure->function->flags & (KRK_CODEOBJECT_FLAGS_IS_GENERATOR | KRK_CODEOBJECT_FLAGS_IS_COROUTINE))) {
KrkInstance * gen = krk_buildGenerator(closure, krk_currentThread.stackTop - argCount, argCount); KrkInstance * gen = krk_buildGenerator(closure, krk_currentThread.stackTop - argCount, argCount);
krk_currentThread.stackTop = krk_currentThread.stackTop - argCount - extra; krk_currentThread.stackTop = krk_currentThread.stackTop - argCount - extra;
krk_push(OBJECT_VAL(gen)); krk_push(OBJECT_VAL(gen));
return 2; return 2;
} }
if (unlikely(krk_currentThread.frameCount == KRK_CALL_FRAMES_MAX)) {
krk_runtimeError(vm.exceptions->baseException, "Too many call frames."); if (unlikely(krk_currentThread.frameCount == KRK_CALL_FRAMES_MAX)) goto _errorAfterKeywords;
return 0;
}
KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount++]; KrkCallFrame * frame = &krk_currentThread.frames[krk_currentThread.frameCount++];
frame->closure = closure; frame->closure = closure;
frame->ip = closure->function->chunk.code; frame->ip = closure->function->chunk.code;
@ -781,18 +778,18 @@ _errorAfterKeywords:
* and it is not necessary to raise another exception. * and it is not necessary to raise another exception.
*/ */
int krk_callValue(KrkValue callee, int argCount, int extra) { int krk_callValue(KrkValue callee, int argCount, int extra) {
if (IS_OBJECT(callee)) { if (likely(IS_OBJECT(callee))) {
switch (OBJECT_TYPE(callee)) { switch (OBJECT_TYPE(callee)) {
case KRK_OBJ_CLOSURE: case KRK_OBJ_CLOSURE:
return call(AS_CLOSURE(callee), argCount, extra); return call(AS_CLOSURE(callee), argCount, extra);
case KRK_OBJ_NATIVE: { case KRK_OBJ_NATIVE: {
NativeFn native = (NativeFn)AS_NATIVE(callee)->function; NativeFn native = (NativeFn)AS_NATIVE(callee)->function;
if (argCount && IS_KWARGS(krk_currentThread.stackTop[-1])) { if (unlikely(argCount && IS_KWARGS(krk_currentThread.stackTop[-1]))) {
KrkValue myList = krk_list_of(0,NULL,0); KrkValue myList = krk_list_of(0,NULL,0);
krk_currentThread.scratchSpace[0] = myList; krk_currentThread.scratchSpace[0] = myList;
KrkValue myDict = krk_dict_of(0,NULL,0); KrkValue myDict = krk_dict_of(0,NULL,0);
krk_currentThread.scratchSpace[1] = myDict; krk_currentThread.scratchSpace[1] = myDict;
if (!krk_processComplexArguments(argCount, AS_LIST(myList), AS_DICT(myDict), AS_NATIVE(callee)->name)) { if (unlikely(!krk_processComplexArguments(argCount, AS_LIST(myList), AS_DICT(myDict), AS_NATIVE(callee)->name))) {
return 0; return 0;
} }
argCount--; /* Because that popped the kwargs value */ argCount--; /* Because that popped the kwargs value */
@ -803,7 +800,7 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
krk_currentThread.scratchSpace[1] = NONE_VAL(); krk_currentThread.scratchSpace[1] = NONE_VAL();
krk_writeValueArray(AS_LIST(myList), myDict); krk_writeValueArray(AS_LIST(myList), myDict);
KrkValue result = native(AS_LIST(myList)->count-1, AS_LIST(myList)->values, 1); KrkValue result = native(AS_LIST(myList)->count-1, AS_LIST(myList)->values, 1);
if (krk_currentThread.stackTop == krk_currentThread.stack) return 0; if (unlikely(krk_currentThread.stackTop == krk_currentThread.stack)) return 0;
krk_pop(); krk_pop();
krk_pop(); krk_pop();
krk_push(result); krk_push(result);
@ -819,7 +816,7 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
result = native(argCount, stackCopy, 0); result = native(argCount, stackCopy, 0);
free(stackCopy); free(stackCopy);
} }
if (krk_currentThread.stackTop == krk_currentThread.stack) return 0; if (unlikely(krk_currentThread.stackTop == krk_currentThread.stack)) return 0;
krk_currentThread.stackTop -= argCount + extra; krk_currentThread.stackTop -= argCount + extra;
krk_push(result); krk_push(result);
} }
@ -828,7 +825,7 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
case KRK_OBJ_INSTANCE: { case KRK_OBJ_INSTANCE: {
KrkClass * _class = AS_INSTANCE(callee)->_class; KrkClass * _class = AS_INSTANCE(callee)->_class;
KrkValue callFunction; KrkValue callFunction;
if (_class->_call) { if (likely(_class->_call)) {
return krk_callValue(OBJECT_VAL(_class->_call), argCount + 1, 0); return krk_callValue(OBJECT_VAL(_class->_call), argCount + 1, 0);
} else if (krk_tableGet(&_class->methods, vm.specialMethodNames[METHOD_CALL], &callFunction)) { } else if (krk_tableGet(&_class->methods, vm.specialMethodNames[METHOD_CALL], &callFunction)) {
return krk_callValue(callFunction, argCount + 1, 0); return krk_callValue(callFunction, argCount + 1, 0);
@ -842,11 +839,11 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
KrkInstance * newInstance = krk_newInstance(_class); KrkInstance * newInstance = krk_newInstance(_class);
krk_currentThread.stackTop[-argCount - 1] = OBJECT_VAL(newInstance); krk_currentThread.stackTop[-argCount - 1] = OBJECT_VAL(newInstance);
KrkValue initializer; KrkValue initializer;
if (_class->_init) { if (likely(_class->_init)) {
return krk_callValue(OBJECT_VAL(_class->_init), argCount + 1, 0); return krk_callValue(OBJECT_VAL(_class->_init), argCount + 1, 0);
} else if (krk_tableGet(&_class->methods, vm.specialMethodNames[METHOD_INIT], &initializer)) { } else if (krk_tableGet(&_class->methods, vm.specialMethodNames[METHOD_INIT], &initializer)) {
return krk_callValue(initializer, argCount + 1, 0); return krk_callValue(initializer, argCount + 1, 0);
} else if (argCount != 0) { } else if (unlikely(argCount != 0)) {
krk_runtimeError(vm.exceptions->typeError, "%s() takes no arguments (%d given)", krk_runtimeError(vm.exceptions->typeError, "%s() takes no arguments (%d given)",
_class->name->chars, argCount); _class->name->chars, argCount);
return 0; return 0;
@ -856,7 +853,7 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
case KRK_OBJ_BOUND_METHOD: { case KRK_OBJ_BOUND_METHOD: {
KrkBoundMethod * bound = AS_BOUND_METHOD(callee); KrkBoundMethod * bound = AS_BOUND_METHOD(callee);
krk_currentThread.stackTop[-argCount - 1] = bound->receiver; krk_currentThread.stackTop[-argCount - 1] = bound->receiver;
if (!bound->method) { if (unlikely(!bound->method)) {
krk_runtimeError(vm.exceptions->argumentError, "???"); krk_runtimeError(vm.exceptions->argumentError, "???");
return 0; return 0;
} }
@ -874,14 +871,13 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
* Takes care of runnext/pop * Takes care of runnext/pop
*/ */
KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod) { KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod) {
int result = krk_callValue(value, argCount, isMethod); switch (krk_callValue(value, argCount, isMethod)) {
if (result == 2) { case 2: return krk_pop();
return krk_pop(); case 1: return krk_runNext();
} else if (result == 1) { default:
return krk_runNext(); if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();
} }
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL(); return krk_runtimeError(vm.exceptions->typeError, "Invalid internal method call: '%s'", krk_typeName(value));
return krk_runtimeError(vm.exceptions->typeError, "Invalid internal method call: %d ('%s')", result, krk_typeName(value));
} }
/** /**