Fixed a hash collision causing null variables to be overwritten
Andrew, don't you dare run my code through a clanker again or I'll hunt your Canuck ass down and beat you with a hockey stick.
This commit is contained in:
@@ -13,7 +13,7 @@ int inspect_bucket(Toy_Bucket** bucketHandle) {
|
|||||||
unsigned char* ptr = iter->data;
|
unsigned char* ptr = iter->data;
|
||||||
|
|
||||||
|
|
||||||
while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition
|
while ((ptr >= iter->data) && (ptr < iter->data + iter->count) && *((int*)ptr) != 0) { //for each partition
|
||||||
if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use?
|
if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use?
|
||||||
occupied++;
|
occupied++;
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -26,7 +26,7 @@ unsigned char* readFile(char* path, int* size) {
|
|||||||
|
|
||||||
//determine the file's length
|
//determine the file's length
|
||||||
fseek(file, 0L, SEEK_END);
|
fseek(file, 0L, SEEK_END);
|
||||||
*size = ftell(file);
|
*size = (int)ftell(file);
|
||||||
rewind(file);
|
rewind(file);
|
||||||
|
|
||||||
//make some space
|
//make some space
|
||||||
@@ -44,7 +44,7 @@ unsigned char* readFile(char* path, int* size) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[(*size)++] = '\0';
|
buffer[(*size)] = '\0';
|
||||||
|
|
||||||
//clean up and return
|
//clean up and return
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@@ -334,7 +334,7 @@ int repl(const char* filepath, bool verbose) {
|
|||||||
inputBuffer[--length] = '\0';
|
inputBuffer[--length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == 0 || !inputBuffer[ strspn(inputBuffer, " \r\n\t") ]) {
|
if (length == 0 || inputBuffer[ strspn(inputBuffer, " \r\n\t") ] == '\0') {
|
||||||
printf("%s> ", prompt); //shows the terminal prompt and restart
|
printf("%s> ", prompt); //shows the terminal prompt and restart
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ static void attr_tableRemove(Toy_VM* vm, Toy_FunctionNative* self) {
|
|||||||
|
|
||||||
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||||
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
|
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
|
||||||
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
|
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_TABLE(compound)->count);
|
||||||
}
|
}
|
||||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "insert")) {
|
else if (MATCH_VALUE_AND_CSTRING(attribute, "insert")) {
|
||||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableInsert);
|
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableInsert);
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ static void emitByte(unsigned char** handle, unsigned int* capacity, unsigned in
|
|||||||
((unsigned char*)(*handle))[(*count)++] = byte;
|
((unsigned char*)(*handle))[(*count)++] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BUG: There might be issues here when compiled on big-endian platforms
|
||||||
static void emitInt(unsigned char** handle, unsigned int* capacity, unsigned int* count, unsigned int bytes) {
|
static void emitInt(unsigned char** handle, unsigned int* capacity, unsigned int* count, unsigned int bytes) {
|
||||||
char* ptr = (char*)&bytes;
|
char* ptr = (char*)&bytes;
|
||||||
emitByte(handle, capacity, count, *(ptr++));
|
emitByte(handle, capacity, count, *(ptr++));
|
||||||
@@ -200,8 +201,8 @@ static unsigned int emitParameters(Toy_Bytecode* mb, Toy_Ast* ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//the address within the data section
|
//the address within the data section
|
||||||
char buffer[128];
|
char buffer[256];
|
||||||
snprintf(buffer, 128, "%.*s", ast->varDeclare.name->info.length, ast->varDeclare.name->leaf.data);
|
snprintf(buffer, 256, "%.*s", ast->varDeclare.name->info.length, ast->varDeclare.name->leaf.data);
|
||||||
unsigned int dataAddr = emitCStringToData(&(mb->data), &(mb->dataCapacity), &(mb->dataCount), buffer);
|
unsigned int dataAddr = emitCStringToData(&(mb->data), &(mb->dataCapacity), &(mb->dataCount), buffer);
|
||||||
|
|
||||||
//check the param index for that entry i.e. don't reuse parameter names
|
//check the param index for that entry i.e. don't reuse parameter names
|
||||||
|
|||||||
+2
-2
@@ -324,7 +324,7 @@ static Toy_AstFlag literal(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
|
|||||||
|
|
||||||
case TOY_TOKEN_LITERAL_INTEGER: {
|
case TOY_TOKEN_LITERAL_INTEGER: {
|
||||||
//filter the '_' character
|
//filter the '_' character
|
||||||
char buffer[parser->previous.length];
|
char buffer[parser->previous.length + 1];
|
||||||
|
|
||||||
unsigned int i = 0, o = 0;
|
unsigned int i = 0, o = 0;
|
||||||
do {
|
do {
|
||||||
@@ -341,7 +341,7 @@ static Toy_AstFlag literal(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
|
|||||||
|
|
||||||
case TOY_TOKEN_LITERAL_FLOAT: {
|
case TOY_TOKEN_LITERAL_FLOAT: {
|
||||||
//filter the '_' character
|
//filter the '_' character
|
||||||
char buffer[parser->previous.length];
|
char buffer[parser->previous.length + 1];
|
||||||
|
|
||||||
unsigned int i = 0, o = 0;
|
unsigned int i = 0, o = 0;
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "toy_print.h"
|
#include "toy_print.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static Toy_callbackType printCallback = puts;
|
static Toy_callbackType printCallback = puts;
|
||||||
@@ -19,14 +20,17 @@ void Toy_assertFailure(const char* msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Toy_setPrintCallback(Toy_callbackType cb) {
|
void Toy_setPrintCallback(Toy_callbackType cb) {
|
||||||
|
assert(cb);
|
||||||
printCallback = cb;
|
printCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toy_setErrorCallback(Toy_callbackType cb) {
|
void Toy_setErrorCallback(Toy_callbackType cb) {
|
||||||
|
assert(cb);
|
||||||
errorCallback = cb;
|
errorCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toy_setAssertFailureCallback(Toy_callbackType cb) {
|
void Toy_setAssertFailureCallback(Toy_callbackType cb) {
|
||||||
|
assert(cb);
|
||||||
assertCallback = cb;
|
assertCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, T
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if this spot is free, insert and return
|
//if this spot is free, insert and return
|
||||||
if (TOY_VALUE_IS_NULL(scope->data[probe].value)) {
|
if (scope->data[probe].key == NULL) { //fuck my life
|
||||||
scope->data[probe] = entry;
|
scope->data[probe] = entry;
|
||||||
scope->count++;
|
scope->count++;
|
||||||
scope->maxPsl = entry.psl > scope->maxPsl ? entry.psl : scope->maxPsl;
|
scope->maxPsl = entry.psl > scope->maxPsl ? entry.psl : scope->maxPsl;
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ static void processRead(Toy_VM* vm) {
|
|||||||
//grab the jump as an integer
|
//grab the jump as an integer
|
||||||
unsigned int jump = *((int*)(vm->code + vm->jumpsAddr + READ_INT(vm)));
|
unsigned int jump = *((int*)(vm->code + vm->jumpsAddr + READ_INT(vm)));
|
||||||
|
|
||||||
|
//BUG: the jump parameter could cause an out of bounds read if it's malformed
|
||||||
|
|
||||||
//jumps are relative to the data address
|
//jumps are relative to the data address
|
||||||
char* cstring = (char*)(vm->code + vm->dataAddr + jump);
|
char* cstring = (char*)(vm->code + vm->dataAddr + jump);
|
||||||
|
|
||||||
|
|||||||
@@ -157,4 +157,11 @@ print !false; //true
|
|||||||
print a;
|
print a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//Yet Another Cosmic Joke
|
||||||
|
var a = null;
|
||||||
|
var i = 42;
|
||||||
|
print a;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: type casting
|
//TODO: type casting
|
||||||
Reference in New Issue
Block a user