Solved a function scope issue

This commit is contained in:
2022-09-05 16:39:09 +10:00
parent 33302ef318
commit f80709ae41
4 changed files with 36 additions and 69 deletions

View File

@@ -102,30 +102,21 @@ void initInterpreter(Interpreter* interpreter) {
}
void freeInterpreter(Interpreter* interpreter) {
//BUGFIX: handle scopes/types in the exports
for (int i = 0; i < interpreter->exports->capacity; i++) {
freeLiteral(interpreter->exports->entries[i].key);
freeLiteral(interpreter->exports->entries[i].value);
freeLiteral(interpreter->exportTypes->entries[i].key);
freeLiteral(interpreter->exportTypes->entries[i].value);
//free the interpreter scope
while(interpreter->scope != NULL) {
interpreter->scope = popScope(interpreter->scope);
}
//BUGFIX: handle scopes of functions, which refer to the parent scope (leaking memory)
while(interpreter->scope != NULL) {
for (int i = 0; i < interpreter->scope->variables.capacity; i++) {
//handle keys, just in case
if (IS_FUNCTION(interpreter->scope->variables.entries[i].key)) {
popScope(AS_FUNCTION(interpreter->scope->variables.entries[i].key).scope);
AS_FUNCTION(interpreter->scope->variables.entries[i].key).scope = NULL;
}
if (IS_FUNCTION(interpreter->scope->variables.entries[i].value)) {
popScope(AS_FUNCTION(interpreter->scope->variables.entries[i].value).scope);
AS_FUNCTION(interpreter->scope->variables.entries[i].value).scope = NULL;
}
//BUGFIX: handle scopes/types in the exports
for (int i = 0; i < interpreter->exports->capacity; i++) {
if (IS_FUNCTION(interpreter->exports->entries[i].key)) {
popScope(AS_FUNCTION(interpreter->exports->entries[i].key).scope);
AS_FUNCTION(interpreter->exports->entries[i].key).scope = NULL;
}
if (IS_FUNCTION(interpreter->exports->entries[i].value)) {
popScope(AS_FUNCTION(interpreter->exports->entries[i].value).scope);
AS_FUNCTION(interpreter->exports->entries[i].value).scope = NULL;
}
interpreter->scope = popScope(interpreter->scope);
}
freeLiteralDictionary(interpreter->exports);
@@ -1850,7 +1841,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
//change the type to normal
interpreter->literalCache.literals[i] = TO_FUNCTION_LITERAL(bytes, size);
AS_FUNCTION(interpreter->literalCache.literals[i]).scope = pushScope(interpreter->scope); //BUGFIX
AS_FUNCTION(interpreter->literalCache.literals[i]).scope = NULL;
}
}

View File

@@ -1195,6 +1195,9 @@ static void importStmt(Parser* parser, Node** nodeHandle) {
emitNodeImport(nodeHandle, NODE_IMPORT, idn, alias);
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of import statement");
freeLiteral(idn);
freeLiteral(alias);
}
static void exportStmt(Parser* parser, Node** nodeHandle) {
@@ -1217,6 +1220,9 @@ static void exportStmt(Parser* parser, Node** nodeHandle) {
emitNodeImport(nodeHandle, NODE_EXPORT, idn, alias);
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of export statement");
freeLiteral(idn);
freeLiteral(alias);
}
//precedence functions

View File

@@ -127,6 +127,20 @@ Scope* popScope(Scope* scope) {
Scope* ret = scope->ancestor;
//BUGFIX: when freeing a scope, free the function's scopes manually
for (int i = 0; i < scope->variables.capacity; i++) {
//handle keys, just in case
if (IS_FUNCTION(scope->variables.entries[i].key)) {
popScope(AS_FUNCTION(scope->variables.entries[i].key).scope);
AS_FUNCTION(scope->variables.entries[i].key).scope = NULL;
}
if (IS_FUNCTION(scope->variables.entries[i].value)) {
popScope(AS_FUNCTION(scope->variables.entries[i].value).scope);
AS_FUNCTION(scope->variables.entries[i].value).scope = NULL;
}
}
freeAncestorChain(scope);
return ret;