Bind globals to functions, not codeobjects
This commit is contained in:
parent
7dc754a519
commit
316d1219a2
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
14
src/object.c
14
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;
|
||||
}
|
||||
|
7
src/vm.c
7
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));
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user