No segfaults, still failing tests

This commit is contained in:
2022-09-01 14:00:31 +10:00
parent 3a4017cea5
commit 90b504d3a4
8 changed files with 64 additions and 33 deletions

View File

@@ -3,13 +3,15 @@
//test arrays without types //test arrays without types
var array = []; var array = [];
assert _length(array) == 0, "_length failed with array";
_push(array, 1); _push(array, 1);
_push(array, 2); _push(array, 2);
_push(array, 3); _push(array, 3);
_push(array, 4); _push(array, 4);
_push(array, "foo"); _push(array, "foo");
assert _length(array) == 5, "_push or _length failed with array"; assert _length(array) == 5, "_push failed with array";
assert _pop(array) == "foo", "_pop failed with array"; assert _pop(array) == "foo", "_pop failed with array";
_set(array, 2, "bar"); _set(array, 2, "bar");
@@ -43,13 +45,15 @@
//test arrays with types //test arrays with types
var array: [int] = []; var array: [int] = [];
assert _length(array) == 0, "_length failed with array (+ types)";
_push(array, 1); _push(array, 1);
_push(array, 2); _push(array, 2);
_push(array, 3); _push(array, 3);
_push(array, 4); _push(array, 4);
_push(array, 10); _push(array, 10);
assert _length(array) == 5, "_push or _length failed with array (+ types)"; assert _length(array) == 5, "_push or failed with array (+ types)";
assert _pop(array) == 10, "_pop failed with array (+ types)"; assert _pop(array) == 10, "_pop failed with array (+ types)";
_set(array, 2, 70); _set(array, 2, 70);

View File

@@ -19,6 +19,8 @@ void initCompiler(Compiler* compiler) {
//separated out, so it can be recursive //separated out, so it can be recursive
static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal literal, bool skipDuplicationOptimisation) { static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal literal, bool skipDuplicationOptimisation) {
bool shouldFree = false;
//if it's a compound type, recurse and store the results //if it's a compound type, recurse and store the results
if (AS_TYPE(literal).typeOf == LITERAL_ARRAY || AS_TYPE(literal).typeOf == LITERAL_DICTIONARY) { if (AS_TYPE(literal).typeOf == LITERAL_ARRAY || AS_TYPE(literal).typeOf == LITERAL_DICTIONARY) {
//I don't like storing types in an array, but it's the easiest and most straight forward method //I don't like storing types in an array, but it's the easiest and most straight forward method
@@ -38,6 +40,7 @@ static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal litera
} }
//push the store to the cache, tweaking the type //push the store to the cache, tweaking the type
shouldFree = true;
literal = TO_ARRAY_LITERAL(store); literal = TO_ARRAY_LITERAL(store);
literal.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea literal.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea
} }
@@ -49,12 +52,16 @@ static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal litera
index = pushLiteralArray(literalCache, literal); index = pushLiteralArray(literalCache, literal);
} }
if (shouldFree) {
freeLiteral(literal); freeLiteral(literal);
}
return index; return index;
} }
else { else {
int index = pushLiteralArray(literalCache, literal); int index = pushLiteralArray(literalCache, literal);
if (shouldFree) {
freeLiteral(literal); freeLiteral(literal);
}
return index; return index;
} }
} }
@@ -411,7 +418,7 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
//embed these in the bytecode... //embed these in the bytecode...
int index = writeNodeCollectionToCache(compiler, node); int index = writeNodeCollectionToCache(compiler, node);
compiler->bytecode[compiler->count] = (unsigned short)index; //2 bytes AS_USHORT(compiler->bytecode[compiler->count]) = (unsigned short)index; //2 bytes
compiler->count += sizeof(unsigned short); compiler->count += sizeof(unsigned short);
} }
break; break;

View File

@@ -75,6 +75,7 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) {
Literal val = arguments->literals[2]; Literal val = arguments->literals[2];
parseIdentifierToValue(interpreter, &obj); parseIdentifierToValue(interpreter, &obj);
parseIdentifierToValue(interpreter, &key);
switch(obj.type) { switch(obj.type) {
case LITERAL_ARRAY: { case LITERAL_ARRAY: {
@@ -99,17 +100,8 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) {
return -1; return -1;
} }
parseIdentifierToValue(interpreter, &val); //don't use pushLiteralArray, since we're setting
val = copyLiteral(val);
//if it's a string or an identifier, make a local copy
if (IS_STRING(val)) {
val = TO_STRING_LITERAL(copyString(AS_STRING(val), strlen(AS_STRING(val)) ), strlen(AS_STRING(val)));
}
if (IS_IDENTIFIER(val)) {
val = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(val), strlen(AS_IDENTIFIER(val)) ), strlen(AS_STRING(val)));
}
//TODO: proper copy function for literals
AS_ARRAY(obj)->literals[AS_INTEGER(key)] = val; AS_ARRAY(obj)->literals[AS_INTEGER(key)] = val;
return 0; return 0;
@@ -197,6 +189,7 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) {
Literal val = arguments->literals[1]; Literal val = arguments->literals[1];
parseIdentifierToValue(interpreter, &obj); parseIdentifierToValue(interpreter, &obj);
parseIdentifierToValue(interpreter, &val);
switch(obj.type) { switch(obj.type) {
case LITERAL_ARRAY: { case LITERAL_ARRAY: {
@@ -211,8 +204,6 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) {
} }
} }
parseIdentifierToValue(interpreter, &val);
pushLiteralArray(AS_ARRAY(obj), val); pushLiteralArray(AS_ARRAY(obj), val);
return 0; return 0;
} }
@@ -261,17 +252,25 @@ int _length(Interpreter* interpreter, LiteralArray* arguments) {
switch(obj.type) { switch(obj.type) {
case LITERAL_ARRAY: { case LITERAL_ARRAY: {
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_ARRAY(obj)->count )); Literal lit = TO_INTEGER_LITERAL( AS_ARRAY(obj)->count );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1; return 1;
} }
case LITERAL_DICTIONARY: case LITERAL_DICTIONARY: {
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count )); Literal lit = TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1; return 1;
}
case LITERAL_STRING: case LITERAL_STRING: {
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) )); Literal lit = TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) );
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
return 1; return 1;
}
default: default:
(interpreter->printOutput)("Incorrect compound type in _length"); (interpreter->printOutput)("Incorrect compound type in _length");
@@ -703,7 +702,6 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) {
return false; return false;
} }
freeLiteral(type);
freeLiteral(val); freeLiteral(val);
return true; return true;
@@ -727,7 +725,7 @@ static bool execFnDecl(Interpreter* interpreter, bool lng) {
Literal identifier = interpreter->literalCache.literals[identifierIndex]; Literal identifier = interpreter->literalCache.literals[identifierIndex];
Literal function = interpreter->literalCache.literals[functionIndex]; Literal function = interpreter->literalCache.literals[functionIndex];
function.as.function.scope = scope; //hacked in function.as.function.scope = pushScope(scope); //hacked in
Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true); Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true);
@@ -1153,6 +1151,7 @@ static bool execFnCall(Interpreter* interpreter) {
inner.bytecode = AS_FUNCTION(func).bytecode; inner.bytecode = AS_FUNCTION(func).bytecode;
inner.length = func.as.function.length; inner.length = func.as.function.length;
inner.count = 0; inner.count = 0;
inner.panic = false;
initLiteralArray(&inner.stack); initLiteralArray(&inner.stack);
setInterpreterPrint(&inner, interpreter->printOutput); setInterpreterPrint(&inner, interpreter->printOutput);
setInterpreterAssert(&inner, interpreter->assertOutput); setInterpreterAssert(&inner, interpreter->assertOutput);
@@ -1178,6 +1177,7 @@ static bool execFnCall(Interpreter* interpreter) {
//free, and skip out //free, and skip out
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner); freeInterpreter(&inner);
return false; return false;
@@ -1190,6 +1190,7 @@ static bool execFnCall(Interpreter* interpreter) {
printf(ERROR "[internal] Could not re-declare parameter\n" RESET); printf(ERROR "[internal] Could not re-declare parameter\n" RESET);
//free, and skip out //free, and skip out
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner); freeInterpreter(&inner);
return false; return false;
} }
@@ -1198,6 +1199,7 @@ static bool execFnCall(Interpreter* interpreter) {
printf(ERROR "[internal] Could not define parameter (bad type?)\n" RESET); printf(ERROR "[internal] Could not define parameter (bad type?)\n" RESET);
//free, and skip out //free, and skip out
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner); freeInterpreter(&inner);
return false; return false;
} }
@@ -1222,6 +1224,7 @@ static bool execFnCall(Interpreter* interpreter) {
freeLiteral(restType); freeLiteral(restType);
freeLiteralArray(&rest); freeLiteralArray(&rest);
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner); freeInterpreter(&inner);
return false; return false;
} }
@@ -1232,6 +1235,7 @@ static bool execFnCall(Interpreter* interpreter) {
freeLiteral(restType); freeLiteral(restType);
freeLiteralArray(&rest); freeLiteralArray(&rest);
freeLiteralArray(&arguments); freeLiteralArray(&arguments);
popScope(inner.scope);
freeInterpreter(&inner); freeInterpreter(&inner);
return false; return false;
} }
@@ -1249,7 +1253,9 @@ static bool execFnCall(Interpreter* interpreter) {
//unpack the results //unpack the results
while (inner.stack.count > 0) { while (inner.stack.count > 0) {
pushLiteralArray(&returns, popLiteralArray(&inner.stack)); //NOTE: also reverses the order Literal lit = popLiteralArray(&inner.stack);
pushLiteralArray(&returns, lit); //NOTE: also reverses the order
freeLiteral(lit);
} }
//TODO: remove this when multiple assignment is enabled - note the BUGFIX that balances the stack //TODO: remove this when multiple assignment is enabled - note the BUGFIX that balances the stack
@@ -1281,6 +1287,7 @@ static bool execFnCall(Interpreter* interpreter) {
} }
pushLiteralArray(&interpreter->stack, ret); //NOTE: reverses again pushLiteralArray(&interpreter->stack, ret); //NOTE: reverses again
freeLiteral(ret);
} }
//free //free
@@ -1306,7 +1313,9 @@ static bool execFnReturn(Interpreter* interpreter) {
//and back again //and back again
while (returns.count > 0) { while (returns.count > 0) {
pushLiteralArray(&interpreter->stack, popLiteralArray(&returns)); Literal lit = popLiteralArray(&returns);
pushLiteralArray(&interpreter->stack, lit);
freeLiteral(lit);
} }
freeLiteralArray(&returns); freeLiteralArray(&returns);
@@ -1700,7 +1709,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) { if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) {
unsigned short vt = readShort(interpreter->bytecode, &interpreter->count); unsigned short vt = readShort(interpreter->bytecode, &interpreter->count);
TYPE_PUSH_SUBTYPE(&typeLiteral, interpreter->literalCache.literals[vt]); TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[vt]));
} }
if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) { if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) {
@@ -1720,7 +1729,7 @@ static void readInterpreterSections(Interpreter* interpreter) {
printf(")\n"); printf(")\n");
} }
freeLiteral(typeLiteral); // freeLiteral(typeLiteral);
} }
break; break;
} }

View File

@@ -78,7 +78,9 @@ Literal copyLiteral(Literal original) {
//copy each element //copy each element
for (int i = 0; i < AS_ARRAY(original)->count; i++) { for (int i = 0; i < AS_ARRAY(original)->count; i++) {
pushLiteralArray(array, copyLiteral(AS_ARRAY(original)->literals[i])); Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]);
pushLiteralArray(array, literal);
freeLiteral(literal);
} }
Literal ret = TO_ARRAY_LITERAL(array); Literal ret = TO_ARRAY_LITERAL(array);
@@ -93,7 +95,7 @@ Literal copyLiteral(Literal original) {
//copy each element //copy each element
for (int i = 0; i < AS_ARRAY(original)->count; i++) { for (int i = 0; i < AS_ARRAY(original)->count; i++) {
Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]); Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]);
pushLiteralArray(array, literal ); pushLiteralArray(array, literal);
freeLiteral(literal); freeLiteral(literal);
} }

View File

@@ -6,6 +6,11 @@
#include <stdlib.h> #include <stdlib.h>
void* reallocate(void* pointer, size_t oldSize, size_t newSize) { void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
if (newSize == 0 && oldSize == 0) {
//causes issues, so just skip out with a NO-OP
return NULL;
}
if (newSize == 0) { if (newSize == 0) {
free(pointer); free(pointer);

View File

@@ -121,6 +121,10 @@ Scope* pushScope(Scope* ancestor) {
} }
Scope* popScope(Scope* scope) { Scope* popScope(Scope* scope) {
if (scope == NULL) { //CAN pop a null
return NULL;
}
Scope* ret = scope->ancestor; Scope* ret = scope->ancestor;
freeAncestorChain(scope); freeAncestorChain(scope);

View File

@@ -16,7 +16,7 @@ all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
../$(OUTDIR)/%.exe: $(ODIR)/%.o ../$(OUTDIR)/%.exe: $(ODIR)/%.o
@$(CC) -o $@ $< $(TARGETS:../source/%.c=$(ODIR)/%.o) $(CFLAGS) $(LIBS) @$(CC) -o $@ $< $(TARGETS:../source/%.c=$(ODIR)/%.o) $(CFLAGS) $(LIBS)
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
valgrind --leak-check=full $@ valgrind --leak-check=full --track-origins=yes $@
else else
@echo please run these tests with valgrind on linux @echo please run these tests with valgrind on linux
endif endif