From 316d1219a2a4b5a0b8ff22da3df48e550eea07c4 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Tue, 12 Jul 2022 09:41:48 +0900 Subject: [PATCH] Bind globals to functions, not codeobjects --- src/compiler.c | 1 - src/kuroko.c | 2 +- src/kuroko/object.h | 5 +++-- src/kuroko/vm.h | 1 + src/memory.c | 2 +- src/obj_gen.c | 2 +- src/object.c | 14 ++++++++++++-- src/vm.c | 7 ++++--- tools/compile.c | 3 +-- 9 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 472baba..87d158a 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -334,7 +334,6 @@ static void initCompiler(Compiler * compiler, FunctionType type) { compiler->scopeDepth = 0; compiler->enclosed = NULL; compiler->codeobject = krk_newCodeObject(); - compiler->codeobject->globalsContext = (KrkInstance*)krk_currentThread.module; compiler->localCount = 0; compiler->localsSpace = 8; compiler->locals = GROW_ARRAY(Local,NULL,0,8); diff --git a/src/kuroko.c b/src/kuroko.c index 98e69c6..f7182cc 100644 --- a/src/kuroko.c +++ b/src/kuroko.c @@ -458,7 +458,7 @@ static int debuggerHook(KrkCallFrame * frame) { krk_debug_disableSingleStep(); /* Turn our compiled expression into a callable. */ krk_push(OBJECT_VAL(expression)); - krk_push(OBJECT_VAL(krk_newClosure(expression))); + krk_push(OBJECT_VAL(krk_newClosure(expression, OBJECT_VAL(krk_currentThread.module)))); krk_swap(1); krk_pop(); /* Stack silliness, don't ask. */ diff --git a/src/kuroko/object.h b/src/kuroko/object.h index 759cbaf..14638cc 100644 --- a/src/kuroko/object.h +++ b/src/kuroko/object.h @@ -158,7 +158,6 @@ typedef struct { size_t localNameCapacity; /**< @brief Capacity of @ref localNames */ size_t localNameCount; /**< @brief Number of entries in @ref localNames */ KrkLocalEntry * localNames; /**< @brief Stores the names of local variables used in the function, for debugging */ - struct KrkInstance * globalsContext; /**< @brief The globals namespace the function should reference when called */ KrkString * qualname; /**< @brief The dotted name of the function */ } KrkCodeObject; @@ -176,6 +175,8 @@ typedef struct { size_t upvalueCount; /**< @brief Number of entries in @ref upvalues */ KrkValue annotations; /**< @brief Dictionary of type hints */ KrkTable fields; /**< @brief Object attributes table */ + KrkValue globalsOwner; /**< @brief Owner of the globals table for this function */ + KrkTable * globalsTable; /**< @brief Pointer to globals table with owner object */ } KrkClosure; typedef void (*KrkCleanupCallback)(struct KrkInstance *); @@ -527,7 +528,7 @@ extern KrkNative * krk_newNative(NativeFn function, const char * name, int * * @param function Code object to assign to the new function object. */ -extern KrkClosure * krk_newClosure(KrkCodeObject * function); +extern KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals); /** * @brief Create an upvalue slot. diff --git a/src/kuroko/vm.h b/src/kuroko/vm.h index 2f13e16..1308a02 100644 --- a/src/kuroko/vm.h +++ b/src/kuroko/vm.h @@ -49,6 +49,7 @@ typedef struct { size_t slots; /**< Offset into the stack at which this function call's arguments begin */ size_t outSlots; /**< Offset into the stack at which stackTop will be reset upon return */ KrkTable * globals; /**< Pointer to the attribute table containing valud global vairables for this call */ + KrkValue globalsOwner; /**< Owner of the current globals context, to give to new closures. */ struct timespec in_time; } KrkCallFrame; diff --git a/src/memory.c b/src/memory.c index 0738ab4..da3277b 100644 --- a/src/memory.c +++ b/src/memory.c @@ -347,6 +347,7 @@ static void blackenObject(KrkObj * object) { } krk_markValue(closure->annotations); krk_markTable(&closure->fields); + krk_markValue(closure->globalsOwner); break; } case KRK_OBJ_CODEOBJECT: { @@ -355,7 +356,6 @@ static void blackenObject(KrkObj * object) { krk_markObject((KrkObj*)function->qualname); krk_markObject((KrkObj*)function->docstring); krk_markObject((KrkObj*)function->chunk.filename); - krk_markObject((KrkObj*)function->globalsContext); markArray(&function->requiredArgNames); markArray(&function->keywordArgNames); markArray(&function->chunk.constants); diff --git a/src/obj_gen.c b/src/obj_gen.c index 2f876ef..5857126 100644 --- a/src/obj_gen.c +++ b/src/obj_gen.c @@ -119,7 +119,7 @@ KRK_Method(generator,__call__) { frame->ip = self->ip; frame->slots = krk_currentThread.stackTop - krk_currentThread.stack; frame->outSlots = frame->slots; - frame->globals = &self->closure->function->globalsContext->fields; + frame->globals = self->closure->globalsTable; /* Stick our stack on their stack */ for (size_t i = 0; i < self->argCount; ++i) { diff --git a/src/object.c b/src/object.c index 348e522..d17d0dd 100644 --- a/src/object.c +++ b/src/object.c @@ -265,7 +265,6 @@ KrkCodeObject * krk_newCodeObject(void) { codeobject->docstring = NULL; codeobject->localNameCount = 0; codeobject->localNames = NULL; - codeobject->globalsContext = NULL; krk_initValueArray(&codeobject->requiredArgNames); krk_initValueArray(&codeobject->keywordArgNames); krk_initChunk(&codeobject->chunk); @@ -281,7 +280,7 @@ KrkNative * krk_newNative(NativeFn function, const char * name, int type) { return native; } -KrkClosure * krk_newClosure(KrkCodeObject * function) { +KrkClosure * krk_newClosure(KrkCodeObject * function, KrkValue globals) { KrkUpvalue ** upvalues = ALLOCATE(KrkUpvalue*, function->upvalueCount); for (size_t i = 0; i < function->upvalueCount; ++i) { upvalues[i] = NULL; @@ -291,6 +290,17 @@ KrkClosure * krk_newClosure(KrkCodeObject * function) { closure->upvalues = upvalues; closure->upvalueCount = function->upvalueCount; closure->annotations = krk_dict_of(0,NULL,0); + closure->globalsOwner = globals; + if (IS_INSTANCE(globals)) { + if (AS_INSTANCE(globals)->_class == vm.baseClasses->dictClass) { + closure->globalsTable = AS_DICT(globals); + } else { + closure->globalsTable = &AS_INSTANCE(globals)->fields; + } + } else { + fprintf(stderr, "Invalid globals context: %s\n", krk_typeName(globals)); + abort(); + } krk_initTable(&closure->fields); return closure; } diff --git a/src/vm.c b/src/vm.c index 004279a..331058c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -925,7 +925,8 @@ _finishKwarg: frame->ip = closure->function->chunk.code; frame->slots = (krk_currentThread.stackTop - argCount) - krk_currentThread.stack; frame->outSlots = frame->slots - returnDepth; - frame->globals = &closure->function->globalsContext->fields; + frame->globalsOwner = closure->globalsOwner; + frame->globals = closure->globalsTable; FRAME_IN(frame); return 1; @@ -3173,7 +3174,7 @@ _finishReturn: (void)0; case OP_CLOSURE: { ONE_BYTE_OPERAND; KrkCodeObject * function = AS_codeobject(READ_CONSTANT(OPERAND)); - KrkClosure * closure = krk_newClosure(function); + KrkClosure * closure = krk_newClosure(function, frame->globalsOwner); krk_push(OBJECT_VAL(closure)); for (size_t i = 0; i < closure->upvalueCount; ++i) { int isLocal = READ_BYTE(); @@ -3577,7 +3578,7 @@ KrkValue krk_interpret(const char * src, char * fromFile) { krk_push(OBJECT_VAL(function)); krk_attachNamedObject(&krk_currentThread.module->fields, "__file__", (KrkObj*)function->chunk.filename); - KrkClosure * closure = krk_newClosure(function); + KrkClosure * closure = krk_newClosure(function, OBJECT_VAL(krk_currentThread.module)); krk_pop(); krk_push(OBJECT_VAL(closure)); diff --git a/tools/compile.c b/tools/compile.c index 6255a58..22454fd 100644 --- a/tools/compile.c +++ b/tools/compile.c @@ -543,7 +543,6 @@ static int readFile(char * fileName) { self->requiredArgs = function.reqArgs; self->keywordArgs = function.kwArgs; self->obj.flags = function.flags; - self->globalsContext = krk_currentThread.module; self->upvalueCount = function.upvalues; self->potentialPositionals = self->requiredArgs + self->keywordArgs; @@ -594,7 +593,7 @@ static int readFile(char * fileName) { krk_pop(); krk_push(AS_LIST(SeenFunctions)->values[0]); - KrkClosure * closure = krk_newClosure(AS_codeobject(krk_peek(0))); + KrkClosure * closure = krk_newClosure(AS_codeobject(krk_peek(0)), OBJECT_VAL(krk_currentThread.module)); krk_pop(); krk_push(OBJECT_VAL(closure));