mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-24 09:03:32 +02:00
big ahh recession
This commit is contained in:
parent
5c3ec01a5a
commit
0961fc0ceb
@ -0,0 +1,18 @@
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
||||
boot/91_gpu.lua:14: attempt to call a nil value (field 'getDepth')
|
@ -2,36 +2,45 @@
|
||||
#include <string.h>
|
||||
#include "component.h"
|
||||
|
||||
nn_componentTable *nn_newComponentTable(const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor) {
|
||||
nn_componentTable *table = nn_malloc(sizeof(nn_componentTable));
|
||||
table->name = nn_strdup(typeName);
|
||||
nn_componentTable *nn_newComponentTable(nn_Alloc *alloc, const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor) {
|
||||
nn_componentTable *table = nn_alloc(alloc, sizeof(nn_componentTable));
|
||||
if(table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
table->name = nn_strdup(alloc, typeName);
|
||||
if(table->name == NULL) {
|
||||
nn_dealloc(alloc, table, sizeof(nn_componentTable));
|
||||
return NULL;
|
||||
}
|
||||
table->userdata = userdata;
|
||||
table->constructor = constructor;
|
||||
table->destructor = destructor;
|
||||
table->methodCount = 0;
|
||||
table->alloc = *alloc;
|
||||
return table;
|
||||
}
|
||||
|
||||
void nn_destroyComponentTable(nn_componentTable *table) {
|
||||
nn_free(table->name);
|
||||
nn_Alloc alloc = table->alloc;
|
||||
nn_deallocStr(&alloc, table->name);
|
||||
for(size_t i = 0; i < table->methodCount; i++) {
|
||||
nn_method method = table->methods[i];
|
||||
nn_free(method.name);
|
||||
nn_free(method.doc);
|
||||
nn_deallocStr(&alloc, method.name);
|
||||
nn_deallocStr(&alloc, method.doc);
|
||||
}
|
||||
nn_free(table);
|
||||
nn_dealloc(&alloc, table, sizeof(nn_componentTable));
|
||||
}
|
||||
|
||||
void nn_defineMethod(nn_componentTable *table, const char *methodName, bool direct, nn_componentMethod *methodFunc, void *methodUserdata, const char *methodDoc) {
|
||||
if(table->methodCount == NN_MAX_METHODS) return;
|
||||
nn_method method;
|
||||
method.method = methodFunc;
|
||||
method.name = nn_strdup(methodName);
|
||||
method.name = nn_strdup(&table->alloc, methodName);
|
||||
if(method.name == NULL) return;
|
||||
method.direct = direct;
|
||||
method.doc = nn_strdup(methodDoc);
|
||||
method.doc = nn_strdup(&table->alloc, methodDoc);
|
||||
if(method.doc == NULL) {
|
||||
nn_free(method.name);
|
||||
nn_deallocStr(&table->alloc, method.name);
|
||||
return;
|
||||
}
|
||||
method.userdata = methodUserdata;
|
||||
|
@ -14,6 +14,7 @@ typedef struct nn_method {
|
||||
|
||||
typedef struct nn_componentTable {
|
||||
char *name;
|
||||
nn_Alloc alloc;
|
||||
void *userdata;
|
||||
nn_componentConstructor *constructor;
|
||||
nn_componentDestructor *destructor;
|
||||
|
@ -21,7 +21,7 @@ void nn_drive_getLabel(nn_drive *drive, void *_, nn_component *component, nn_com
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
}
|
||||
}
|
||||
void nn_drive_setLabel(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -33,7 +33,7 @@ void nn_drive_setLabel(nn_drive *drive, void *_, nn_component *component, nn_com
|
||||
return;
|
||||
}
|
||||
l = drive->setLabel(component, drive->userdata, buf, l);
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
}
|
||||
void nn_drive_getSectorSize(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t sector_size = drive->getSectorSize(component, drive->userdata);
|
||||
@ -53,7 +53,7 @@ void nn_drive_readSector(nn_drive *drive, void *_, nn_component *component, nn_c
|
||||
size_t sector_size = drive->getSectorSize(component, drive->userdata);
|
||||
char buf[sector_size];
|
||||
drive->readSector(component, drive->userdata, sector, buf);
|
||||
nn_return(computer, nn_values_string(buf, sector_size));
|
||||
nn_return_string(computer, buf, sector_size);
|
||||
}
|
||||
void nn_drive_writeSector(nn_drive *drive, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_value sectorValue = nn_getArgument(computer, 0);
|
||||
@ -93,7 +93,7 @@ void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_co
|
||||
}
|
||||
|
||||
void nn_loadDriveTable(nn_universe *universe) {
|
||||
nn_componentTable *driveTable = nn_newComponentTable("drive", NULL, NULL, (void *)nn_drive_destroy);
|
||||
nn_componentTable *driveTable = nn_newComponentTable(nn_getAllocator(universe), "drive", NULL, NULL, (void *)nn_drive_destroy);
|
||||
nn_storeUserdata(universe, "NN:DRIVE", driveTable);
|
||||
|
||||
nn_defineMethod(driveTable, "getLabel", false, (void *)nn_drive_getLabel, NULL, "getLabel():string - Get the current label of the drive.");
|
||||
|
@ -41,7 +41,7 @@ void nn_eeprom_getLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
}
|
||||
|
||||
// Latency, energy costs and stuff
|
||||
@ -61,7 +61,7 @@ void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_
|
||||
return;
|
||||
}
|
||||
l = eeprom->setLabel(component, eeprom->userdata, buf, l);
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
|
||||
// Latency, energy costs and stuff
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, eeprom);
|
||||
@ -74,14 +74,15 @@ void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_
|
||||
|
||||
void nn_eeprom_get(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
}
|
||||
size_t len = eeprom->get(component, eeprom->userdata, buf);
|
||||
nn_return(computer, nn_values_string(buf, len));
|
||||
nn_free(buf);
|
||||
nn_return_string(computer, buf, len);
|
||||
nn_dealloc(alloc, buf, cap);
|
||||
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, eeprom);
|
||||
nn_randomLatency(control.randomLatencyMin, control.randomLatencyMax);
|
||||
@ -119,7 +120,8 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu
|
||||
|
||||
void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
@ -128,9 +130,9 @@ void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c
|
||||
if(len < 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, len));
|
||||
nn_return_string(computer, buf, len);
|
||||
}
|
||||
nn_free(buf);
|
||||
nn_dealloc(alloc, buf, cap);
|
||||
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, eeprom);
|
||||
nn_randomLatency(control.randomLatencyMin, control.randomLatencyMax);
|
||||
@ -178,7 +180,8 @@ void nn_eeprom_makeReadonly(nn_eeprom *eeprom, void *_, nn_component *component,
|
||||
// TODO: make good
|
||||
void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
|
||||
size_t cap = eeprom->getDataSize(component, eeprom->userdata);
|
||||
char *buf = nn_malloc(cap);
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, cap);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
@ -188,9 +191,9 @@ void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component,
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
sum += buf[i];
|
||||
}
|
||||
nn_free(buf);
|
||||
nn_dealloc(alloc, buf, cap);
|
||||
|
||||
nn_return(computer, nn_values_string((void *)&sum, sizeof(sum)));
|
||||
nn_return_string(computer, (void *)&sum, sizeof(sum));
|
||||
|
||||
nn_eepromControl control = nn_eeprom_getControl(component, eeprom);
|
||||
nn_randomLatency(control.randomLatencyMin, control.randomLatencyMax);
|
||||
@ -200,7 +203,7 @@ void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component,
|
||||
}
|
||||
|
||||
void nn_loadEepromTable(nn_universe *universe) {
|
||||
nn_componentTable *eepromTable = nn_newComponentTable("eeprom", NULL, NULL, (void *)nn_eeprom_destroy);
|
||||
nn_componentTable *eepromTable = nn_newComponentTable(nn_getAllocator(universe), "eeprom", NULL, NULL, (void *)nn_eeprom_destroy);
|
||||
nn_storeUserdata(universe, "NN:EEPROM", eepromTable);
|
||||
|
||||
nn_defineMethod(eepromTable, "getSize", true, (void *)nn_eeprom_getSize, NULL, "getSize(): integer - Returns the maximum code capacity of the EEPROM.");
|
||||
|
@ -69,7 +69,7 @@ void nn_fs_getLabel(nn_filesystem *fs, void *_, nn_component *component, nn_comp
|
||||
if(l == 0) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
} else {
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
}
|
||||
|
||||
// Latency, energy costs and stuff
|
||||
@ -89,7 +89,7 @@ void nn_fs_setLabel(nn_filesystem *fs, void *_, nn_component *component, nn_comp
|
||||
return;
|
||||
}
|
||||
l = fs->setLabel(component, fs->userdata, buf, l);
|
||||
nn_return(computer, nn_values_string(buf, l));
|
||||
nn_return_string(computer, buf, l);
|
||||
|
||||
nn_fs_readCost(fs, 1, component, computer);
|
||||
}
|
||||
@ -271,17 +271,19 @@ void nn_fs_list(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
return;
|
||||
}
|
||||
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
|
||||
size_t fileCount = 0;
|
||||
char **files = fs->list(component, fs->userdata, path, &fileCount);
|
||||
char **files = fs->list(alloc, component, fs->userdata, path, &fileCount);
|
||||
|
||||
if(files != NULL) {
|
||||
// operation succeeded
|
||||
nn_value arr = nn_values_array(fileCount);
|
||||
nn_value arr = nn_values_array(alloc, fileCount);
|
||||
for(size_t i = 0; i < fileCount; i++) {
|
||||
nn_values_set(arr, i, nn_values_string(files[i], strlen(files[i])));
|
||||
nn_free(files[i]);
|
||||
nn_values_set(arr, i, nn_values_string(alloc, files[i], strlen(files[i])));
|
||||
nn_deallocStr(alloc, files[i]);
|
||||
}
|
||||
nn_free(files);
|
||||
nn_dealloc(alloc, files, sizeof(char *) * fileCount);
|
||||
nn_return(computer, arr);
|
||||
}
|
||||
|
||||
@ -356,7 +358,8 @@ void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
if(len > capacity) len = capacity;
|
||||
size_t byteLen = len;
|
||||
|
||||
char *buf = nn_malloc(byteLen);
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
char *buf = nn_alloc(alloc, byteLen);
|
||||
if(buf == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
@ -365,9 +368,9 @@ void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
size_t readLen = fs->read(component, fs->userdata, fd, buf, byteLen);
|
||||
if(readLen > 0) {
|
||||
// Nothing read means EoF.
|
||||
nn_return(computer, nn_values_string(buf, readLen));
|
||||
nn_return_string(computer, buf, readLen);
|
||||
}
|
||||
nn_free(buf);
|
||||
nn_dealloc(alloc, buf, byteLen);
|
||||
|
||||
// do not ask where it comes from, balance is hard
|
||||
nn_fs_readCost(fs, nn_fs_countChunks(fs, readLen, component), component, computer);
|
||||
@ -410,7 +413,7 @@ void nn_fs_seek(nn_filesystem *fs, void *_, nn_component *component, nn_computer
|
||||
}
|
||||
|
||||
void nn_loadFilesystemTable(nn_universe *universe) {
|
||||
nn_componentTable *fsTable = nn_newComponentTable("filesystem", NULL, NULL, (void *)nn_fs_destroy);
|
||||
nn_componentTable *fsTable = nn_newComponentTable(nn_getAllocator(universe), "filesystem", NULL, NULL, (void *)nn_fs_destroy);
|
||||
nn_storeUserdata(universe, "NN:FILESYSTEM", fsTable);
|
||||
|
||||
nn_defineMethod(fsTable, "getLabel", false, (void *)nn_fs_getLabel, NULL, "getLabel(): string - Returns the label of the filesystem.");
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
|
||||
typedef struct nni_gpu {
|
||||
nn_Alloc alloc;
|
||||
nn_screen *currentScreen;
|
||||
nn_address screenAddress;
|
||||
nn_gpuControl ctrl;
|
||||
@ -34,8 +35,10 @@ bool nni_inBounds(nni_gpu *gpu, int x, int y) {
|
||||
true;
|
||||
}
|
||||
|
||||
nni_gpu *nni_newGPU(nn_gpuControl *ctrl) {
|
||||
nni_gpu *gpu = nn_malloc(sizeof(nni_gpu));
|
||||
nni_gpu *nni_newGPU(nn_Alloc *alloc, nn_gpuControl *ctrl) {
|
||||
nni_gpu *gpu = nn_alloc(alloc, sizeof(nni_gpu));
|
||||
if(gpu == NULL) return NULL;
|
||||
gpu->alloc = *alloc;
|
||||
gpu->currentScreen = NULL;
|
||||
gpu->screenAddress = NULL;
|
||||
gpu->ctrl = *ctrl;
|
||||
@ -50,10 +53,11 @@ void nni_gpuDeinit(nni_gpu *gpu) {
|
||||
if(gpu->currentScreen != NULL) {
|
||||
nn_destroyScreen(gpu->currentScreen);
|
||||
}
|
||||
nn_Alloc a = gpu->alloc;
|
||||
if(gpu->screenAddress != NULL) {
|
||||
nn_free(gpu->screenAddress);
|
||||
nn_deallocStr(&a, gpu->screenAddress);
|
||||
}
|
||||
nn_free(gpu);
|
||||
nn_dealloc(&a, gpu, sizeof(nni_gpu));
|
||||
}
|
||||
|
||||
nn_scrchr_t nni_gpu_makePixel(nni_gpu *gpu, const char *s) {
|
||||
@ -111,9 +115,9 @@ void nni_gpu_bind(nni_gpu *gpu, void *_, nn_component *component, nn_computer *c
|
||||
|
||||
gpu->currentScreen = screen;
|
||||
if(gpu->screenAddress != NULL) {
|
||||
nn_free(gpu->screenAddress);
|
||||
nn_deallocStr(&gpu->alloc, gpu->screenAddress);
|
||||
}
|
||||
gpu->screenAddress = nn_strdup(addr);
|
||||
gpu->screenAddress = nn_strdup(&gpu->alloc, addr);
|
||||
|
||||
nn_addHeat(computer, gpu->ctrl.bindHeat);
|
||||
nn_callCost(computer, gpu->ctrl.bindCost);
|
||||
@ -170,7 +174,7 @@ void nni_gpu_get(nni_gpu *gpu, void *_, nn_component *component, nn_computer *co
|
||||
|
||||
void nni_gpu_getScreen(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) {
|
||||
if(gpu->screenAddress == NULL) return;
|
||||
nn_return(computer, nn_values_string(gpu->screenAddress, 0));
|
||||
nn_return_string(computer, gpu->screenAddress, 0);
|
||||
}
|
||||
|
||||
void nni_gpu_maxResolution(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) {
|
||||
@ -360,7 +364,7 @@ void nni_gpu_copy(nni_gpu *gpu, void *_, nn_component *component, nn_computer *c
|
||||
|
||||
int changes = 0, clears = 0;
|
||||
|
||||
nn_scrchr_t *tmpBuffer = nn_malloc(sizeof(nn_scrchr_t) * w * h);
|
||||
nn_scrchr_t *tmpBuffer = nn_alloc(&gpu->alloc, sizeof(nn_scrchr_t) * w * h);
|
||||
if(tmpBuffer == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
@ -388,7 +392,7 @@ void nni_gpu_copy(nni_gpu *gpu, void *_, nn_component *component, nn_computer *c
|
||||
}
|
||||
}
|
||||
|
||||
nn_free(tmpBuffer);
|
||||
nn_dealloc(&gpu->alloc, tmpBuffer, sizeof(nn_scrchr_t) * w * h);
|
||||
|
||||
nn_addHeat(computer, gpu->ctrl.pixelChangeHeat * changes);
|
||||
nn_callCost(computer, gpu->ctrl.pixelChangeCost * changes);
|
||||
@ -411,7 +415,7 @@ void nni_gpu_getViewport(nni_gpu *gpu, void *_, nn_component *component, nn_comp
|
||||
}
|
||||
|
||||
void nn_loadGraphicsCardTable(nn_universe *universe) {
|
||||
nn_componentTable *gpuTable = nn_newComponentTable("gpu", NULL, NULL, (void *)nni_gpuDeinit);
|
||||
nn_componentTable *gpuTable = nn_newComponentTable(nn_getAllocator(universe), "gpu", NULL, NULL, (void *)nni_gpuDeinit);
|
||||
nn_storeUserdata(universe, "NN:GPU", gpuTable);
|
||||
|
||||
nn_defineMethod(gpuTable, "bind", false, (void *)nni_gpu_bind, NULL, "bind(addr: string[, reset: boolean = false]): boolean - Bind a GPU to a screen. Very expensive. If reset is true, it will clear the screen.");
|
||||
@ -432,7 +436,7 @@ void nn_loadGraphicsCardTable(nn_universe *universe) {
|
||||
|
||||
nn_component *nn_addGPU(nn_computer *computer, nn_address address, int slot, nn_gpuControl *control) {
|
||||
nn_componentTable *gpuTable = nn_queryUserdata(nn_getUniverse(computer), "NN:GPU");
|
||||
nni_gpu *gpu = nni_newGPU(control);
|
||||
nni_gpu *gpu = nni_newGPU(nn_getAllocator(nn_getUniverse(computer)), control);
|
||||
if(gpu == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "../neonucleus.h"
|
||||
|
||||
void nn_loadKeyboardTable(nn_universe *universe) {
|
||||
nn_componentTable *keyboardTable = nn_newComponentTable("keyboard", NULL, NULL, NULL);
|
||||
nn_componentTable *keyboardTable = nn_newComponentTable(nn_getAllocator(universe), "keyboard", NULL, NULL, NULL);
|
||||
nn_storeUserdata(universe, "NN:KEYBOARD", keyboardTable);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include "screen.h"
|
||||
#include <string.h>
|
||||
|
||||
nn_screen *nn_newScreen(int maxWidth, int maxHeight, int maxDepth, int editableColors, int paletteColors) {
|
||||
nn_screen *screen = nn_malloc(sizeof(nn_screen));
|
||||
screen->buffer = nn_malloc(sizeof(nn_scrchr_t) * maxWidth * maxHeight);
|
||||
screen->lock = nn_newGuard();
|
||||
nn_screen *nn_newScreen(nn_Alloc *alloc, int maxWidth, int maxHeight, int maxDepth, int editableColors, int paletteColors) {
|
||||
nn_screen *screen = nn_alloc(alloc, sizeof(nn_screen));
|
||||
screen->alloc = *alloc;
|
||||
screen->buffer = nn_alloc(alloc, sizeof(nn_scrchr_t) * maxWidth * maxHeight);
|
||||
screen->lock = nn_newGuard(alloc);
|
||||
screen->refc = 1;
|
||||
screen->width = maxWidth;
|
||||
screen->height = maxHeight;
|
||||
@ -16,7 +17,7 @@ nn_screen *nn_newScreen(int maxWidth, int maxHeight, int maxDepth, int editableC
|
||||
screen->depth = maxDepth;
|
||||
screen->editableColors = editableColors;
|
||||
screen->paletteColors = paletteColors;
|
||||
screen->palette = nn_malloc(sizeof(int) * screen->paletteColors);
|
||||
screen->palette = nn_alloc(alloc, sizeof(int) * screen->paletteColors);
|
||||
memset(screen->palette, 0, sizeof(int) * screen->paletteColors);
|
||||
screen->aspectRatioWidth = 1;
|
||||
screen->aspectRatioHeight = 1;
|
||||
@ -34,10 +35,11 @@ void nn_retainScreen(nn_screen *screen) {
|
||||
|
||||
void nn_destroyScreen(nn_screen *screen) {
|
||||
if(!nn_decRef(&screen->refc)) return;
|
||||
nn_deleteGuard(screen->lock);
|
||||
nn_free(screen->buffer);
|
||||
nn_free(screen->palette);
|
||||
nn_free(screen);
|
||||
nn_Alloc a = screen->alloc;
|
||||
nn_deleteGuard(&a, screen->lock);
|
||||
nn_dealloc(&a, screen->buffer, sizeof(nn_scrchr_t) * screen->maxWidth * screen->maxHeight);
|
||||
nn_dealloc(&a, screen->palette, sizeof(int) * screen->paletteColors);
|
||||
nn_dealloc(&a, screen, sizeof(nn_screen));
|
||||
}
|
||||
|
||||
void nn_lockScreen(nn_screen *screen) {
|
||||
@ -85,14 +87,14 @@ void nn_setAspectRatio(nn_screen *screen, int width, int height) {
|
||||
|
||||
void nn_addKeyboard(nn_screen *screen, nn_address address) {
|
||||
if(screen->keyboardCount == NN_MAX_SCREEN_KEYBOARDS) return;
|
||||
screen->keyboards[screen->keyboardCount++] = nn_strdup(address);
|
||||
screen->keyboards[screen->keyboardCount++] = nn_strdup(&screen->alloc, address);
|
||||
}
|
||||
|
||||
void nn_removeKeyboard(nn_screen *screen, nn_address address) {
|
||||
size_t j = 0;
|
||||
for(size_t i = 0; i < screen->keyboardCount; i++) {
|
||||
if(strcmp(screen->keyboards[i], address) == 0) {
|
||||
nn_free(screen->keyboards[i]);
|
||||
nn_deallocStr(&screen->alloc, screen->keyboards[i]);
|
||||
} else {
|
||||
screen->keyboards[j] = screen->keyboards[i];
|
||||
j++;
|
||||
@ -206,12 +208,12 @@ void nn_screenComp_destroy(void *_, nn_component *component, nn_screen *screen)
|
||||
|
||||
void nn_screenComp_getKeyboards(nn_screen *screen, void *_, nn_component *component, nn_computer *computer) {
|
||||
nn_lockScreen(screen);
|
||||
nn_value arr = nn_values_array(nn_getKeyboardCount(screen));
|
||||
nn_value arr = nn_values_array(&screen->alloc, nn_getKeyboardCount(screen));
|
||||
|
||||
size_t len = arr.array->len;
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
size_t addrlen = strlen(nn_getKeyboard(screen, i));
|
||||
nn_value addr = nn_values_string(nn_getKeyboard(screen, i), addrlen);
|
||||
nn_value addr = nn_values_string(&screen->alloc, nn_getKeyboard(screen, i), addrlen);
|
||||
nn_values_set(arr, i, addr);
|
||||
}
|
||||
|
||||
@ -220,7 +222,7 @@ void nn_screenComp_getKeyboards(nn_screen *screen, void *_, nn_component *compon
|
||||
}
|
||||
|
||||
void nn_loadScreenTable(nn_universe *universe) {
|
||||
nn_componentTable *screenTable = nn_newComponentTable("screen", NULL, NULL, (void *)nn_screenComp_destroy);
|
||||
nn_componentTable *screenTable = nn_newComponentTable(nn_getAllocator(universe), "screen", NULL, NULL, (void *)nn_screenComp_destroy);
|
||||
nn_storeUserdata(universe, "NN:SCREEN", screenTable);
|
||||
|
||||
nn_defineMethod(screenTable, "getKeyboards", false, (void *)nn_screenComp_getKeyboards, NULL, "getKeyboards(): string[] - Returns the keyboards registered to this screen.");
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../neonucleus.h"
|
||||
|
||||
typedef struct nn_screen {
|
||||
nn_Alloc alloc;
|
||||
nn_scrchr_t *buffer;
|
||||
nn_guard *lock;
|
||||
nn_refc refc;
|
||||
|
122
src/computer.c
122
src/computer.c
@ -1,26 +1,27 @@
|
||||
#include "computer.h"
|
||||
#include "component.h"
|
||||
#include "universe.h"
|
||||
#include "neonucleus.h"
|
||||
#include <string.h>
|
||||
|
||||
nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_architecture *arch, void *userdata, size_t memoryLimit, size_t componentLimit) {
|
||||
nn_computer *c = nn_malloc(sizeof(nn_computer));
|
||||
c->components = nn_malloc(sizeof(nn_component) * componentLimit);
|
||||
nn_computer *c = nn_alloc(&universe->alloc, sizeof(nn_computer));
|
||||
c->components = nn_alloc(&universe->alloc, sizeof(nn_component) * componentLimit);
|
||||
if(c->components == NULL) {
|
||||
nn_free(c);
|
||||
nn_dealloc(&universe->alloc, c, sizeof(nn_computer));
|
||||
return NULL;
|
||||
}
|
||||
c->address = nn_strdup(address);
|
||||
c->address = nn_strdup(&universe->alloc, address);
|
||||
if(c->address == NULL) {
|
||||
nn_free(c->components);
|
||||
nn_free(c);
|
||||
nn_dealloc(&universe->alloc, c->components, sizeof(nn_component) * componentLimit);
|
||||
nn_dealloc(&universe->alloc, c, sizeof(nn_computer));
|
||||
return NULL;
|
||||
}
|
||||
c->lock = nn_newGuard();
|
||||
c->lock = nn_newGuard(&universe->alloc);
|
||||
if(c->lock == NULL) {
|
||||
nn_free(c->address);
|
||||
nn_free(c->components);
|
||||
nn_free(c);
|
||||
nn_deallocStr(&universe->alloc, c->address);
|
||||
nn_dealloc(&universe->alloc, c->components, sizeof(nn_component) * componentLimit);
|
||||
nn_dealloc(&universe->alloc, c, sizeof(nn_computer));
|
||||
return NULL;
|
||||
}
|
||||
c->timeOffset = nn_getTime(universe);
|
||||
@ -50,10 +51,10 @@ nn_computer *nn_newComputer(nn_universe *universe, nn_address address, nn_archit
|
||||
// Setup Architecture
|
||||
c->archState = c->arch->setup(c, c->arch->userdata);
|
||||
if(c->archState == NULL) {
|
||||
nn_deleteGuard(c->lock);
|
||||
nn_free(c->address);
|
||||
nn_free(c->components);
|
||||
nn_free(c);
|
||||
nn_deleteGuard(&universe->alloc, c->lock);
|
||||
nn_deallocStr(&universe->alloc, c->address);
|
||||
nn_dealloc(&universe->alloc, c->components, sizeof(nn_component) * componentLimit);
|
||||
nn_dealloc(&universe->alloc, c, sizeof(nn_computer));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -65,8 +66,8 @@ nn_universe *nn_getUniverse(nn_computer *computer) {
|
||||
}
|
||||
|
||||
void nn_setTmpAddress(nn_computer *computer, nn_address tmp) {
|
||||
nn_free(computer->tmpAddress);
|
||||
computer->tmpAddress = nn_strdup(tmp);
|
||||
nn_deallocStr(&computer->universe->alloc, computer->tmpAddress);
|
||||
computer->tmpAddress = nn_strdup(&computer->universe->alloc, tmp);
|
||||
}
|
||||
|
||||
nn_address nn_getComputerAddress(nn_computer *computer) {
|
||||
@ -130,15 +131,15 @@ void nn_deleteComputer(nn_computer *computer) {
|
||||
while(computer->signalCount > 0) {
|
||||
nn_popSignal(computer);
|
||||
}
|
||||
nn_Alloc *a = &computer->universe->alloc;
|
||||
for(size_t i = 0; i < computer->userCount; i++) {
|
||||
nn_free(computer->users[i]);
|
||||
nn_deallocStr(a, computer->users[i]);
|
||||
}
|
||||
computer->arch->teardown(computer, computer->archState, computer->arch->userdata);
|
||||
nn_deleteGuard(computer->lock);
|
||||
nn_free(computer->components);
|
||||
nn_free(computer->address);
|
||||
nn_free(computer->tmpAddress);
|
||||
nn_free(computer);
|
||||
nn_deleteGuard(a, computer->lock);
|
||||
nn_deallocStr(a, computer->address);
|
||||
nn_dealloc(a, computer->components, sizeof(nn_component) * computer->componentCap);
|
||||
nn_dealloc(a, computer->components, sizeof(nn_computer));
|
||||
}
|
||||
|
||||
const char *nn_pushSignal(nn_computer *computer, nn_value *values, size_t len) {
|
||||
@ -183,7 +184,7 @@ void nn_popSignal(nn_computer *computer) {
|
||||
|
||||
const char *nn_addUser(nn_computer *computer, const char *name) {
|
||||
if(computer->userCount == NN_MAX_USERS) return "too many users";
|
||||
char *user = nn_strdup(name);
|
||||
char *user = nn_strdup(&computer->universe->alloc, name);
|
||||
if(user == NULL) return "out of memory";
|
||||
computer->users[computer->userCount] = user;
|
||||
computer->userCount++;
|
||||
@ -195,7 +196,7 @@ void nn_deleteUser(nn_computer *computer, const char *name) {
|
||||
for(size_t i = 0; i < computer->userCount; i++) {
|
||||
char *user = computer->users[i];
|
||||
if(strcmp(user, name) == 0) {
|
||||
nn_free(user);
|
||||
nn_deallocStr(&computer->universe->alloc, user);
|
||||
} else {
|
||||
computer->users[j] = user;
|
||||
j++;
|
||||
@ -322,7 +323,7 @@ const char *nn_getError(nn_computer *computer) {
|
||||
|
||||
void nn_clearError(nn_computer *computer) {
|
||||
if(computer->allocatedError) {
|
||||
nn_free(computer->err);
|
||||
nn_deallocStr(&computer->universe->alloc, computer->err);
|
||||
}
|
||||
computer->err = NULL;
|
||||
computer->allocatedError = false;
|
||||
@ -330,7 +331,7 @@ void nn_clearError(nn_computer *computer) {
|
||||
|
||||
void nn_setError(nn_computer *computer, const char *err) {
|
||||
nn_clearError(computer);
|
||||
char *copy = nn_strdup(err);
|
||||
char *copy = nn_strdup(&computer->universe->alloc, err);
|
||||
if(copy == NULL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
return;
|
||||
@ -360,7 +361,7 @@ nn_component *nn_newComponent(nn_computer *computer, nn_address address, int slo
|
||||
computer->componentLen++;
|
||||
}
|
||||
|
||||
c->address = nn_strdup(address);
|
||||
c->address = nn_strdup(&computer->universe->alloc, address);
|
||||
if(c->address == NULL) return NULL;
|
||||
c->table = table;
|
||||
c->slot = slot;
|
||||
@ -382,7 +383,7 @@ void nn_removeComponent(nn_computer *computer, nn_address address) {
|
||||
}
|
||||
|
||||
void nn_destroyComponent(nn_component *component) {
|
||||
nn_free(component->address);
|
||||
nn_deallocStr(&component->computer->universe->alloc, component->address);
|
||||
if(component->table->destructor != NULL) {
|
||||
component->table->destructor(component->table->userdata, component, component->statePtr);
|
||||
}
|
||||
@ -391,6 +392,7 @@ void nn_destroyComponent(nn_component *component) {
|
||||
|
||||
nn_component *nn_findComponent(nn_computer *computer, nn_address address) {
|
||||
for(size_t i = 0; i < computer->componentLen; i++) {
|
||||
if(computer->components[i].address == NULL) continue; // empty slot
|
||||
if(strcmp(computer->components[i].address, address) == 0) {
|
||||
return computer->components + i;
|
||||
}
|
||||
@ -398,19 +400,13 @@ nn_component *nn_findComponent(nn_computer *computer, nn_address address) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nn_component **nn_listComponent(nn_computer *computer, size_t *len) {
|
||||
nn_component **c = nn_malloc(sizeof(nn_component *) * computer->componentLen);
|
||||
if(c == NULL) return NULL;
|
||||
size_t j = 0;
|
||||
for(size_t i = 0; i < computer->componentLen; i++) {
|
||||
nn_component *component = computer->components + i;
|
||||
if(component->address != NULL) {
|
||||
c[j] = component;
|
||||
j++;
|
||||
}
|
||||
nn_component *nn_iterComponent(nn_computer *computer, size_t *internalIndex) {
|
||||
for(size_t i = *internalIndex; i < computer->componentLen; i++) {
|
||||
if(computer->components[i].address == NULL) continue;
|
||||
*internalIndex = i+1;
|
||||
return computer->components + i;
|
||||
}
|
||||
*len = j;
|
||||
return c;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nn_resetCall(nn_computer *computer) {
|
||||
@ -471,3 +467,49 @@ void nn_lockComputer(nn_computer *computer) {
|
||||
void nn_unlockComputer(nn_computer *computer) {
|
||||
nn_unlock(computer->lock);
|
||||
}
|
||||
|
||||
void nn_return_nil(nn_computer *computer) {
|
||||
nn_return(computer, nn_values_nil());
|
||||
}
|
||||
|
||||
void nn_return_integer(nn_computer *computer, intptr_t integer) {
|
||||
nn_return(computer, nn_values_integer(integer));
|
||||
}
|
||||
|
||||
void nn_return_number(nn_computer *computer, double number) {
|
||||
nn_return(computer, nn_values_number(number));
|
||||
}
|
||||
|
||||
void nn_return_boolean(nn_computer *computer, bool boolean) {
|
||||
nn_return(computer, nn_values_boolean(boolean));
|
||||
}
|
||||
|
||||
void nn_return_cstring(nn_computer *computer, const char *cstr) {
|
||||
nn_return(computer, nn_values_cstring(cstr));
|
||||
}
|
||||
|
||||
void nn_return_string(nn_computer *computer, const char *str, size_t len) {
|
||||
nn_value val = nn_values_string(&computer->universe->alloc, str, len);
|
||||
if(val.tag == NN_VALUE_NIL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
}
|
||||
nn_return(computer, val);
|
||||
}
|
||||
|
||||
nn_value nn_return_array(nn_computer *computer, size_t len) {
|
||||
nn_value val = nn_values_array(&computer->universe->alloc, len);
|
||||
if(val.tag == NN_VALUE_NIL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
}
|
||||
nn_return(computer, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
nn_value nn_return_table(nn_computer *computer, size_t len) {
|
||||
nn_value val = nn_values_table(&computer->universe->alloc, len);
|
||||
if(val.tag == NN_VALUE_NIL) {
|
||||
nn_setCError(computer, "out of memory");
|
||||
}
|
||||
nn_return(computer, val);
|
||||
return val;
|
||||
}
|
||||
|
@ -184,16 +184,16 @@ size_t ne_fs_read(nn_component *component, ne_fs *fs, int fd, char *buf, size_t
|
||||
return fread(buf, sizeof(char), required, f);
|
||||
}
|
||||
|
||||
char **ne_fs_list(nn_component *component, ne_fs *fs, const char *path, size_t *len) {
|
||||
char **ne_fs_list(nn_Alloc *alloc, nn_component *component, ne_fs *fs, const char *path, size_t *len) {
|
||||
const char *p = ne_fs_diskPath(component, path);
|
||||
if(p[0] == '/') p++;
|
||||
|
||||
FilePathList files = LoadDirectoryFiles(p);
|
||||
*len = files.count;
|
||||
|
||||
char **buf = nn_malloc(sizeof(char *) * files.count);
|
||||
char **buf = nn_alloc(alloc, sizeof(char *) * files.count);
|
||||
for(size_t i = 0; i < files.count; i++) {
|
||||
buf[i] = nn_strdup(GetFileName(files.paths[i]));
|
||||
buf[i] = nn_strdup(alloc, GetFileName(files.paths[i]));
|
||||
}
|
||||
|
||||
UnloadDirectoryFiles(files);
|
||||
@ -466,7 +466,12 @@ int keycode_to_oc(int keycode) {
|
||||
|
||||
int main() {
|
||||
printf("Setting up universe\n");
|
||||
nn_universe *universe = nn_newUniverse();
|
||||
nn_Alloc alloc = nn_libcAllocator();
|
||||
nn_universe *universe = nn_newUniverse(alloc);
|
||||
if(universe == NULL) {
|
||||
printf("Failed to create universe\n");
|
||||
return 1;
|
||||
}
|
||||
nn_loadCoreComponentTables(universe);
|
||||
|
||||
nn_architecture *arch = testLuaArch_getArchitecture("src/sandbox.lua");
|
||||
@ -528,7 +533,7 @@ int main() {
|
||||
};
|
||||
nn_addFileSystem(computer, "OpenOS", 1, &genericFS);
|
||||
|
||||
nn_screen *s = nn_newScreen(80, 32, 16, 16, 256);
|
||||
nn_screen *s = nn_newScreen(&alloc, 80, 32, 16, 16, 256);
|
||||
nn_addKeyboard(s, "shitty keyboard");
|
||||
nn_mountKeyboard(computer, "shitty keyboard", 2);
|
||||
nn_addScreen(computer, "Main Screen", 2, s);
|
||||
|
@ -5,8 +5,8 @@ typedef struct nn_guard {
|
||||
mtx_t m;
|
||||
} nn_guard;
|
||||
|
||||
nn_guard *nn_newGuard() {
|
||||
nn_guard *g = nn_malloc(sizeof(nn_guard));
|
||||
nn_guard *nn_newGuard(nn_Alloc *alloc) {
|
||||
nn_guard *g = nn_alloc(alloc, sizeof(nn_guard));
|
||||
if(g == NULL) return NULL;
|
||||
mtx_init(&g->m, mtx_recursive);
|
||||
return g;
|
||||
@ -22,9 +22,10 @@ void nn_unlock(nn_guard *guard) {
|
||||
mtx_unlock(&guard->m);
|
||||
}
|
||||
|
||||
void nn_deleteGuard(nn_guard *guard) {
|
||||
void nn_deleteGuard(nn_Alloc *alloc, nn_guard *guard) {
|
||||
if(guard == NULL) return;
|
||||
mtx_destroy(&guard->m);
|
||||
nn_dealloc(alloc, guard, sizeof(nn_guard));
|
||||
}
|
||||
|
||||
void nn_addRef(nn_refc *refc, size_t count) {
|
||||
|
@ -90,6 +90,23 @@ typedef struct nn_architecture {
|
||||
} nn_architecture;
|
||||
typedef char *nn_address;
|
||||
|
||||
// A non-zero malloc is a null ptr, with a 0 oldSize, but a non-0 newSize.
|
||||
// A zero malloc is never called, the proc address itself is returned, which is ignored when freeing.
|
||||
// A free is a non-null ptr, with a non-zero oldSize, but a newSize of 0.
|
||||
// A realloc is a non-null ptr, with a non-zero oldSize, and a non-zero newSize.
|
||||
typedef void *nn_AllocProc(void *userdata, void *ptr, size_t oldSize, size_t newSize, void *extra);
|
||||
|
||||
typedef struct nn_Alloc {
|
||||
void *userdata;
|
||||
nn_AllocProc *proc;
|
||||
} nn_Alloc;
|
||||
|
||||
// TODO: write a bunch of utils so this *can* work on baremetal.
|
||||
|
||||
#ifndef NN_BAREMETAL
|
||||
nn_Alloc nn_libcAllocator();
|
||||
#endif
|
||||
|
||||
// Values for architectures
|
||||
|
||||
#define NN_VALUE_INT 0
|
||||
@ -105,18 +122,21 @@ typedef struct nn_string {
|
||||
char *data;
|
||||
size_t len;
|
||||
size_t refc;
|
||||
nn_Alloc alloc;
|
||||
} nn_string;
|
||||
|
||||
typedef struct nn_array {
|
||||
struct nn_value *values;
|
||||
size_t len;
|
||||
size_t refc;
|
||||
nn_Alloc alloc;
|
||||
} nn_array;
|
||||
|
||||
typedef struct nn_object {
|
||||
struct nn_pair *pairs;
|
||||
size_t len;
|
||||
size_t refc;
|
||||
nn_Alloc alloc;
|
||||
} nn_table;
|
||||
|
||||
typedef struct nn_value {
|
||||
@ -138,18 +158,19 @@ typedef struct nn_pair {
|
||||
} nn_pair;
|
||||
|
||||
// we expose the allocator because of some utilities
|
||||
void *nn_malloc(size_t size);
|
||||
void *nn_realloc(void *memory, size_t newSize);
|
||||
void nn_free(void *memory);
|
||||
void *nn_alloc(nn_Alloc *alloc, size_t size);
|
||||
void *nn_resize(nn_Alloc *alloc, void *memory, size_t oldSize, size_t newSize);
|
||||
void nn_dealloc(nn_Alloc *alloc, void *memory, size_t size);
|
||||
|
||||
// Utilities, both internal and external
|
||||
char *nn_strdup(const char *s);
|
||||
void *nn_memdup(const void *buf, size_t len);
|
||||
char *nn_strdup(nn_Alloc *alloc, const char *s);
|
||||
void *nn_memdup(nn_Alloc *alloc, const void *buf, size_t len);
|
||||
void nn_deallocStr(nn_Alloc *alloc, char *s);
|
||||
|
||||
nn_guard *nn_newGuard();
|
||||
nn_guard *nn_newGuard(nn_Alloc *alloc);
|
||||
void nn_lock(nn_guard *guard);
|
||||
void nn_unlock(nn_guard *guard);
|
||||
void nn_deleteGuard(nn_guard *guard);
|
||||
void nn_deleteGuard(nn_Alloc *alloc, nn_guard *guard);
|
||||
|
||||
void nn_addRef(nn_refc *refc, size_t count);
|
||||
void nn_incRef(nn_refc *refc);
|
||||
@ -159,10 +180,10 @@ bool nn_removeRef(nn_refc *refc, size_t count);
|
||||
bool nn_decRef(nn_refc *refc);
|
||||
|
||||
bool nn_unicode_validate(const char *s);
|
||||
// returned string must be nn_free()'d
|
||||
char *nn_unicode_char(unsigned int *codepoints, size_t codepointCount);
|
||||
// returned array must be nn_free()'d
|
||||
unsigned int *nn_unicode_codepoints(const char *s);
|
||||
// returned string must be nn_deallocStr()'d
|
||||
char *nn_unicode_char(nn_Alloc *alloc, unsigned int *codepoints, size_t codepointCount);
|
||||
// returned array must be nn_dealloc()'d
|
||||
unsigned int *nn_unicode_codepoints(nn_Alloc *alloc, const char *s, size_t *len);
|
||||
size_t nn_unicode_len(const char *s);
|
||||
unsigned int nn_unicode_codepointAt(const char *s, size_t byteOffset);
|
||||
size_t nn_unicode_codepointSize(unsigned int codepoint);
|
||||
@ -170,9 +191,11 @@ const char *nn_unicode_codepointToChar(unsigned int codepoint, size_t *len);
|
||||
size_t nn_unicode_charWidth(unsigned int codepoint);
|
||||
size_t nn_unicode_wlen(const char *s);
|
||||
unsigned int nn_unicode_upperCodepoint(unsigned int codepoint);
|
||||
char *nn_unicode_upper(const char *s);
|
||||
// returned string must be nn_deallocStr()'d
|
||||
char *nn_unicode_upper(nn_Alloc *alloc, const char *s);
|
||||
unsigned int nn_unicode_lowerCodepoint(unsigned int codepoint);
|
||||
char *nn_unicode_lower(const char *s);
|
||||
// returned string must be nn_deallocStr()'d
|
||||
char *nn_unicode_lower(nn_Alloc *alloc, const char *s);
|
||||
|
||||
double nn_realTime();
|
||||
double nn_realTimeClock(void *_);
|
||||
@ -183,7 +206,8 @@ void nn_randomLatency(double min, double max);
|
||||
|
||||
typedef double nn_clock_t(void *_);
|
||||
|
||||
nn_universe *nn_newUniverse();
|
||||
nn_universe *nn_newUniverse(nn_Alloc alloc);
|
||||
nn_Alloc *nn_getAllocator(nn_universe *universe);
|
||||
void nn_unsafeDeleteUniverse(nn_universe *universe);
|
||||
void *nn_queryUserdata(nn_universe *universe, const char *name);
|
||||
void nn_storeUserdata(nn_universe *universe, const char *name, void *data);
|
||||
@ -300,8 +324,11 @@ nn_componentTable *nn_getComponentTable(nn_component *component);
|
||||
const char *nn_getComponentType(nn_componentTable *table);
|
||||
void *nn_getComponentUserdata(nn_component *component);
|
||||
nn_component *nn_findComponent(nn_computer *computer, nn_address address);
|
||||
/* RESULT SHOULD BE NN_FREE()'D OR ELSE MEMORY IS LEAKED */
|
||||
nn_component **nn_listComponent(nn_computer *computer, size_t *len);
|
||||
// the internal index is not the array index, but rather an index into
|
||||
// an internal structure. YOU SHOULD NOT ADD OR REMOVE COMPONENTS WHILE ITERATING.
|
||||
// the internalIndex SHOULD BE INITIALIZED TO 0.
|
||||
// Returns NULL at the end
|
||||
nn_component *nn_iterComponent(nn_computer *computer, size_t *internalIndex);
|
||||
|
||||
// Component VTable stuff
|
||||
|
||||
@ -309,7 +336,7 @@ typedef void *nn_componentConstructor(void *tableUserdata, void *componentUserda
|
||||
typedef void *nn_componentDestructor(void *tableUserdata, nn_component *component, void *componentUserdata);
|
||||
typedef void nn_componentMethod(void *componentUserdata, void *methodUserdata, nn_component *component, nn_computer *computer);
|
||||
|
||||
nn_componentTable *nn_newComponentTable(const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor);
|
||||
nn_componentTable *nn_newComponentTable(nn_Alloc *alloc, const char *typeName, void *userdata, nn_componentConstructor *constructor, nn_componentDestructor *destructor);
|
||||
void nn_destroyComponentTable(nn_componentTable *table);
|
||||
void nn_defineMethod(nn_componentTable *table, const char *methodName, bool direct, nn_componentMethod *methodFunc, void *methodUserdata, const char *methodDoc);
|
||||
const char *nn_getTableMethod(nn_componentTable *table, size_t idx, bool *outDirect);
|
||||
@ -334,9 +361,18 @@ nn_value nn_values_integer(intptr_t integer);
|
||||
nn_value nn_values_number(double num);
|
||||
nn_value nn_values_boolean(bool boolean);
|
||||
nn_value nn_values_cstring(const char *string);
|
||||
nn_value nn_values_string(const char *string, size_t len);
|
||||
nn_value nn_values_array(size_t len);
|
||||
nn_value nn_values_table(size_t pairCount);
|
||||
nn_value nn_values_string(nn_Alloc *alloc, const char *string, size_t len);
|
||||
nn_value nn_values_array(nn_Alloc *alloc, size_t len);
|
||||
nn_value nn_values_table(nn_Alloc *alloc, size_t pairCount);
|
||||
|
||||
void nn_return_nil(nn_computer *computer);
|
||||
void nn_return_integer(nn_computer *computer, intptr_t integer);
|
||||
void nn_return_number(nn_computer *computer, double number);
|
||||
void nn_return_boolean(nn_computer *computer, bool boolean);
|
||||
void nn_return_cstring(nn_computer *computer, const char *cstr);
|
||||
void nn_return_string(nn_computer *computer, const char *str, size_t len);
|
||||
nn_value nn_return_array(nn_computer *computer, size_t len);
|
||||
nn_value nn_return_table(nn_computer *computer, size_t len);
|
||||
|
||||
size_t nn_values_getType(nn_value val);
|
||||
nn_value nn_values_retain(nn_value val);
|
||||
@ -471,10 +507,13 @@ typedef struct nn_filesystem {
|
||||
// directory operations
|
||||
bool (*isDirectory)(nn_component *component, void *userdata, const char *path);
|
||||
bool (*makeDirectory)(nn_component *component, void *userdata, const char *path);
|
||||
// the length and array must be nn_alloc'd.
|
||||
// The strings must be NULL-terminated and also nn_alloc'd.
|
||||
// See nn_strdup().
|
||||
char **(*list)(nn_component *component, void *userdata, const char *path, size_t *len);
|
||||
// The returned array should be allocated with the supplied allocator.
|
||||
// The strings should be null terminated. Use nn_strdup for the allocation to guarantee nn_deallocStr deallocates it correctly.
|
||||
// For the array, the *exact* size of the allocation should be sizeof(char *) * (*len),
|
||||
// If it is not, the behavior is undefined.
|
||||
// We recommend first computing len then allocating, though if that is not doable or practical,
|
||||
// consider nn_resize()ing it to the correct size to guarantee a correct deallocation.
|
||||
char **(*list)(nn_Alloc *alloc, nn_component *component, void *userdata, const char *path, size_t *len);
|
||||
|
||||
// file operations
|
||||
size_t (*open)(nn_component *component, void *userdata, const char *path, const char *mode);
|
||||
@ -549,7 +588,7 @@ typedef struct nn_scrchr_t {
|
||||
bool isBgPalette;
|
||||
} nn_scrchr_t;
|
||||
|
||||
nn_screen *nn_newScreen(int maxWidth, int maxHeight, int maxDepth, int editableColors, int paletteColors);
|
||||
nn_screen *nn_newScreen(nn_Alloc *alloc, int maxWidth, int maxHeight, int maxDepth, int editableColors, int paletteColors);
|
||||
nn_componentTable *nn_getScreenTable(nn_universe *universe);
|
||||
|
||||
void nn_retainScreen(nn_screen *screen);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "neonucleus.h"
|
||||
|
||||
@ -40,6 +41,13 @@ testLuaArch *testLuaArch_get(lua_State *L) {
|
||||
return arch;
|
||||
}
|
||||
|
||||
nn_Alloc *testLuaArch_getAlloc(lua_State *L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "archPtr");
|
||||
testLuaArch *arch = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return nn_getAllocator(nn_getUniverse(arch->computer));
|
||||
}
|
||||
|
||||
const char *testLuaArch_pushlstring(lua_State *L, const char *s, size_t len) {
|
||||
if (lua_checkstack(L, 1) == 0) {
|
||||
return NULL;
|
||||
@ -58,9 +66,10 @@ const char *testLuaArch_pushstring(lua_State *L, const char *s) {
|
||||
|
||||
|
||||
void *testLuaArch_alloc(testLuaArch *arch, void *ptr, size_t osize, size_t nsize) {
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(arch->computer));
|
||||
if(nsize == 0) {
|
||||
arch->memoryUsed -= osize;
|
||||
nn_free(ptr);
|
||||
free(ptr);
|
||||
return NULL;
|
||||
} else {
|
||||
size_t actualOldSize = osize;
|
||||
@ -70,7 +79,7 @@ void *testLuaArch_alloc(testLuaArch *arch, void *ptr, size_t osize, size_t nsize
|
||||
}
|
||||
arch->memoryUsed -= actualOldSize;
|
||||
arch->memoryUsed += nsize;
|
||||
return nn_realloc(ptr, nsize);
|
||||
return realloc(ptr, nsize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +89,7 @@ nn_computer *testLuaArch_getComputer(lua_State *L) {
|
||||
|
||||
static nn_value testLuaArch_getValue(lua_State *L, int index) {
|
||||
int type = lua_type(L, index);
|
||||
nn_Alloc *alloc = testLuaArch_getAlloc(L);
|
||||
|
||||
if(type == LUA_TBOOLEAN) {
|
||||
return nn_values_boolean(lua_toboolean(L, index));
|
||||
@ -90,7 +100,7 @@ static nn_value testLuaArch_getValue(lua_State *L, int index) {
|
||||
if(type == LUA_TSTRING) {
|
||||
size_t l = 0;
|
||||
const char *s = lua_tolstring(L, index, &l);
|
||||
return nn_values_string(s, l);
|
||||
return nn_values_string(alloc, s, l);
|
||||
}
|
||||
if(type == LUA_TNUMBER && lua_isinteger(L, index)) {
|
||||
return nn_values_integer(lua_tointeger(L, index));
|
||||
@ -330,17 +340,12 @@ static int testLuaArch_computer_setState(lua_State *L) {
|
||||
|
||||
static int testLuaArch_component_list(lua_State *L) {
|
||||
nn_computer *c = testLuaArch_getComputer(L);
|
||||
size_t len = 0;
|
||||
nn_component **components = nn_listComponent(c, &len);
|
||||
if(components == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "out of memory");
|
||||
return 2;
|
||||
}
|
||||
lua_createtable(L, 0, len);
|
||||
lua_createtable(L, 0, 10);
|
||||
size_t iter = 0;
|
||||
int list = lua_gettop(L);
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
nn_component *component = components[i];
|
||||
while(true) {
|
||||
nn_component *component = nn_iterComponent(c, &iter);
|
||||
if(component == NULL) break;
|
||||
nn_componentTable *table = nn_getComponentTable(component);
|
||||
nn_address addr = nn_getComponentAddress(component);
|
||||
const char *type = nn_getComponentType(table);
|
||||
@ -348,7 +353,6 @@ static int testLuaArch_component_list(lua_State *L) {
|
||||
lua_pushstring(L, type);
|
||||
lua_setfield(L, list, addr);
|
||||
}
|
||||
nn_free(components);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -463,6 +467,7 @@ static int testLuaArch_component_invoke(lua_State *L) {
|
||||
|
||||
int testLuaArch_unicode_sub(lua_State *L) {
|
||||
const char *s = luaL_checkstring(L, 1);
|
||||
nn_Alloc *alloc = testLuaArch_getAlloc(L);
|
||||
int start = luaL_checkinteger(L, 2);
|
||||
if(!nn_unicode_validate(s)) {
|
||||
luaL_error(L, "invalid utf-8");
|
||||
@ -500,15 +505,20 @@ int testLuaArch_unicode_sub(lua_State *L) {
|
||||
|
||||
// there is a way to do it without an allocation
|
||||
// however, I'm lazy
|
||||
unsigned int *points = nn_unicode_codepoints(s);
|
||||
size_t pointLen;
|
||||
unsigned int *points = nn_unicode_codepoints(alloc, s, &pointLen);
|
||||
if(points == NULL) {
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
|
||||
char *sub = nn_unicode_char(points + start - 1, stop - start + 1);
|
||||
char *sub = nn_unicode_char(alloc, points + start - 1, stop - start + 1);
|
||||
if(sub == NULL) {
|
||||
nn_dealloc(alloc, points, sizeof(unsigned int) * pointLen);
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
const char *res = testLuaArch_pushstring(L, sub);
|
||||
nn_free(sub);
|
||||
nn_free(points);
|
||||
nn_deallocStr(alloc, sub);
|
||||
nn_dealloc(alloc, points, sizeof(unsigned int) * pointLen);
|
||||
if (!res) {
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
@ -518,23 +528,24 @@ int testLuaArch_unicode_sub(lua_State *L) {
|
||||
|
||||
int testLuaArch_unicode_char(lua_State *L) {
|
||||
int argc = lua_gettop(L);
|
||||
unsigned int *codepoints = nn_malloc(sizeof(unsigned int) * argc);
|
||||
nn_Alloc *alloc = testLuaArch_getAlloc(L);
|
||||
unsigned int *codepoints = nn_alloc(alloc, sizeof(unsigned int) * argc);
|
||||
if(codepoints == NULL) {
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
for(int i = 0; i < argc; i++) {
|
||||
int idx = i + 1;
|
||||
if(!lua_isinteger(L, idx)) {
|
||||
nn_free(codepoints);
|
||||
nn_dealloc(alloc, codepoints, sizeof(unsigned int) * argc);
|
||||
luaL_argerror(L, idx, "integer expected");
|
||||
return 0;
|
||||
}
|
||||
codepoints[i] = lua_tointeger(L, idx);
|
||||
}
|
||||
char *s = nn_unicode_char(codepoints, argc);
|
||||
char *s = nn_unicode_char(alloc, codepoints, argc);
|
||||
const char *res = testLuaArch_pushstring(L, s);
|
||||
nn_free(s);
|
||||
nn_free(codepoints);
|
||||
nn_deallocStr(alloc, s);
|
||||
nn_dealloc(alloc, codepoints, sizeof(unsigned int) * argc);
|
||||
if (!res) {
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
@ -649,7 +660,8 @@ void testLuaArch_loadEnv(lua_State *L) {
|
||||
}
|
||||
|
||||
testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) {
|
||||
testLuaArch *s = nn_malloc(sizeof(testLuaArch));
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
testLuaArch *s = nn_alloc(alloc, sizeof(testLuaArch));
|
||||
if(s == NULL) return NULL;
|
||||
s->memoryUsed = 0;
|
||||
s->computer = computer;
|
||||
@ -665,8 +677,9 @@ testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) {
|
||||
}
|
||||
|
||||
void testLuaArch_teardown(nn_computer *computer, testLuaArch *arch, void *_) {
|
||||
nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer));
|
||||
lua_close(arch->L);
|
||||
nn_free(arch);
|
||||
nn_dealloc(alloc, arch, sizeof(testLuaArch));
|
||||
}
|
||||
|
||||
void testLuaArch_tick(nn_computer *computer, testLuaArch *arch, void *_) {
|
||||
@ -719,7 +732,7 @@ nn_architecture *testLuaArch_getArchitecture(const char *sandboxPath) {
|
||||
if(f == NULL) return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t l = ftell(f);
|
||||
testLuaSandbox = nn_malloc(l+1);
|
||||
testLuaSandbox = malloc(l+1);
|
||||
if(testLuaSandbox == NULL) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
|
@ -205,14 +205,14 @@ bool nn_unicode_validate(const char *b) {
|
||||
// It is used to power the Lua architecture's Unicode API re-implementation.
|
||||
// It can also just be used to deal with unicode.
|
||||
|
||||
char *nn_unicode_char(unsigned int *codepoints, size_t codepointCount) {
|
||||
char *nn_unicode_char(nn_Alloc *alloc, unsigned int *codepoints, size_t codepointCount) {
|
||||
size_t len = 0;
|
||||
for (size_t i = 0; i < codepointCount; i++) {
|
||||
unsigned int codepoint = codepoints[i];
|
||||
len += nn_unicode_codepointSize(codepoint);
|
||||
}
|
||||
|
||||
char *buf = nn_malloc(len+1);
|
||||
char *buf = nn_alloc(alloc, len+1);
|
||||
if (buf == NULL) return buf;
|
||||
|
||||
size_t j = 0;
|
||||
@ -224,15 +224,18 @@ char *nn_unicode_char(unsigned int *codepoints, size_t codepointCount) {
|
||||
j += codepointLen;
|
||||
}
|
||||
buf[j] = '\0';
|
||||
assert(j == len); // better safe than sorry
|
||||
// this can only fail if size_t is smaller than a pointer and overflowed.
|
||||
// IF THIS HAPPENS, THE SYSTEM HEADERS ARE BUGGED.
|
||||
assert(j == len);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
unsigned int *nn_unicode_codepoints(const char *s) {
|
||||
unsigned int *nn_unicode_codepoints(nn_Alloc *alloc, const char *s, size_t *len) {
|
||||
size_t l = nn_unicode_len(s);
|
||||
unsigned int *buf = nn_malloc(sizeof(unsigned int) * l);
|
||||
unsigned int *buf = nn_alloc(alloc, sizeof(unsigned int) * l);
|
||||
if(buf == NULL) return NULL;
|
||||
if(len != NULL) *len = l;
|
||||
size_t cur = 0;
|
||||
size_t bufidx = 0;
|
||||
while(s[cur] != 0) {
|
||||
@ -363,6 +366,6 @@ size_t nn_unicode_wlen(const char *s) {
|
||||
// NOT IMPLEMENTED YET
|
||||
|
||||
unsigned int nn_unicode_upperCodepoint(unsigned int codepoint);
|
||||
char *nn_unicode_upper(const char *s);
|
||||
char *nn_unicode_upper(nn_Alloc *alloc, const char *s);
|
||||
unsigned int nn_unicode_lowerCodepoint(unsigned int codepoint);
|
||||
char *nn_unicode_lower(const char *s);
|
||||
char *nn_unicode_lower(nn_Alloc *alloc, const char *s);
|
||||
|
@ -2,9 +2,10 @@
|
||||
#include "universe.h"
|
||||
#include <string.h>
|
||||
|
||||
nn_universe *nn_newUniverse() {
|
||||
nn_universe *u = nn_malloc(sizeof(nn_universe));
|
||||
nn_universe *nn_newUniverse(nn_Alloc alloc) {
|
||||
nn_universe *u = nn_alloc(&alloc, sizeof(nn_universe));
|
||||
if(u == NULL) return u;
|
||||
u->alloc = alloc;
|
||||
// we leave udata uninitialized because it does not matter
|
||||
u->udataLen = 0;
|
||||
u->clockUserdata = NULL;
|
||||
@ -12,11 +13,15 @@ nn_universe *nn_newUniverse() {
|
||||
return u;
|
||||
}
|
||||
|
||||
nn_Alloc *nn_getAllocator(nn_universe *universe) {
|
||||
return &universe->alloc;
|
||||
}
|
||||
|
||||
void nn_unsafeDeleteUniverse(nn_universe *universe) {
|
||||
for(size_t i = 0; i < universe->udataLen; i++) {
|
||||
nn_free(universe->udata[i].name);
|
||||
nn_deallocStr(&universe->alloc, universe->udata[i].name);
|
||||
}
|
||||
nn_free(universe);
|
||||
nn_dealloc(&universe->alloc, universe, sizeof(nn_universe));
|
||||
}
|
||||
|
||||
void *nn_queryUserdata(nn_universe *universe, const char *name) {
|
||||
@ -32,7 +37,7 @@ void nn_storeUserdata(nn_universe *universe, const char *name, void *data) {
|
||||
if(universe->udataLen == NN_MAX_USERDATA) return; // prevent overflow
|
||||
|
||||
size_t idx = universe->udataLen;
|
||||
char *allocName = nn_strdup(name);
|
||||
char *allocName = nn_strdup(&universe->alloc, name);
|
||||
if(allocName == NULL) return;
|
||||
|
||||
universe->udata[idx].name = allocName;
|
||||
|
@ -9,6 +9,7 @@ typedef struct nn_universe_udata {
|
||||
} nn_universe_udata;
|
||||
|
||||
typedef struct nn_universe {
|
||||
nn_Alloc alloc;
|
||||
nn_universe_udata udata[NN_MAX_USERDATA];
|
||||
size_t udataLen;
|
||||
nn_clock_t *currentClock;
|
||||
|
61
src/utils.c
61
src/utils.c
@ -1,4 +1,5 @@
|
||||
#include "neonucleus.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -8,32 +9,71 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
void *nn_malloc(size_t size) {
|
||||
return malloc(size);
|
||||
void *nn_alloc(nn_Alloc *alloc, size_t size) {
|
||||
if(size == 0) return alloc->proc;
|
||||
return alloc->proc(alloc->userdata, NULL, 0, size, NULL);
|
||||
}
|
||||
|
||||
void *nn_realloc(void *memory, size_t newSize) {
|
||||
return realloc(memory, newSize);
|
||||
void *nn_resize(nn_Alloc *alloc, void *memory, size_t oldSize, size_t newSize) {
|
||||
if(oldSize == newSize) return memory;
|
||||
if(newSize == 0) {
|
||||
nn_dealloc(alloc, memory, oldSize);
|
||||
return alloc->proc;
|
||||
}
|
||||
if(memory == NULL) {
|
||||
return nn_alloc(alloc, newSize);
|
||||
}
|
||||
if(memory == alloc->proc) {
|
||||
if(newSize == 0) return memory;
|
||||
return nn_alloc(alloc, newSize);
|
||||
}
|
||||
return alloc->proc(alloc->userdata, memory, oldSize, newSize, NULL);
|
||||
}
|
||||
|
||||
void nn_free(void *memory) {
|
||||
free(memory);
|
||||
void nn_dealloc(nn_Alloc *alloc, void *memory, size_t size) {
|
||||
if(memory == NULL) return; // matches free()
|
||||
if(memory == alloc->proc) return; // 0-sized memory
|
||||
alloc->proc(alloc->userdata, memory, size, 0, NULL);
|
||||
}
|
||||
|
||||
static void *nn_libcAllocProc(void *_, void *ptr, size_t oldSize, size_t newSize, void *__) {
|
||||
if(newSize == 0) {
|
||||
//printf("Freed %lu bytes from %p\n", oldSize, ptr);
|
||||
free(ptr);
|
||||
return NULL;
|
||||
} else {
|
||||
void *rptr = realloc(ptr, newSize);
|
||||
//printf("Allocated %lu bytes for %p\n", newSize - oldSize, rptr);
|
||||
return rptr;
|
||||
}
|
||||
}
|
||||
|
||||
nn_Alloc nn_libcAllocator() {
|
||||
return (nn_Alloc) {
|
||||
.userdata = NULL,
|
||||
.proc = nn_libcAllocProc,
|
||||
};
|
||||
}
|
||||
|
||||
// Utilities, both internal and external
|
||||
char *nn_strdup(const char *s) {
|
||||
char *nn_strdup(nn_Alloc *alloc, const char *s) {
|
||||
size_t l = strlen(s);
|
||||
char *m = nn_malloc(l+1);
|
||||
char *m = nn_alloc(alloc, l+1);
|
||||
if(m == NULL) return m;
|
||||
return strcpy(m, s);
|
||||
}
|
||||
|
||||
void *nn_memdup(const void *buf, size_t len) {
|
||||
char *m = malloc(len);
|
||||
void *nn_memdup(nn_Alloc *alloc, const void *buf, size_t len) {
|
||||
char *m = nn_alloc(alloc, len);
|
||||
if(m == NULL) return m;
|
||||
return memcpy(m, buf, len);
|
||||
}
|
||||
|
||||
void nn_deallocStr(nn_Alloc *alloc, char *s) {
|
||||
if(s == NULL) return;
|
||||
nn_dealloc(alloc, s, strlen(s)+1);
|
||||
}
|
||||
|
||||
#ifdef NN_POSIX
|
||||
|
||||
double nn_realTime() {
|
||||
@ -71,3 +111,4 @@ void nn_randomLatency(double min, double max) {
|
||||
double latency = min + t * (max - min);
|
||||
nn_busySleep(latency);
|
||||
}
|
||||
|
||||
|
44
src/value.c
44
src/value.c
@ -21,38 +21,38 @@ nn_value nn_values_cstring(const char *string) {
|
||||
return (nn_value) {.tag = NN_VALUE_CSTR, .cstring = string};
|
||||
}
|
||||
|
||||
nn_value nn_values_string(const char *string, size_t len) {
|
||||
if(len == 0) len = strlen(string);
|
||||
|
||||
char *buf = nn_malloc(len+1);
|
||||
nn_value nn_values_string(nn_Alloc *alloc, const char *string, size_t len) {
|
||||
char *buf = nn_alloc(alloc, len+1);
|
||||
if(buf == NULL) {
|
||||
return nn_values_nil();
|
||||
}
|
||||
memcpy(buf, string, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
nn_string *s = nn_malloc(sizeof(nn_string));
|
||||
nn_string *s = nn_alloc(alloc, sizeof(nn_string));
|
||||
if(s == NULL) {
|
||||
nn_free(buf);
|
||||
nn_dealloc(alloc, buf, len+1);
|
||||
return nn_values_nil();
|
||||
}
|
||||
s->data = buf;
|
||||
s->len = len;
|
||||
s->refc = 1;
|
||||
s->alloc = *alloc;
|
||||
|
||||
return (nn_value) {.tag = NN_VALUE_STR, .string = s};
|
||||
}
|
||||
|
||||
nn_value nn_values_array(size_t len) {
|
||||
nn_array *arr = nn_malloc(sizeof(nn_array));
|
||||
nn_value nn_values_array(nn_Alloc *alloc, size_t len) {
|
||||
nn_array *arr = nn_alloc(alloc, sizeof(nn_array));
|
||||
if(arr == NULL) {
|
||||
return nn_values_nil();
|
||||
}
|
||||
arr->alloc = *alloc;
|
||||
arr->refc = 1;
|
||||
arr->len = len;
|
||||
nn_value *values = nn_malloc(sizeof(nn_value) * len);
|
||||
nn_value *values = nn_alloc(alloc, sizeof(nn_value) * len);
|
||||
if(values == NULL) {
|
||||
nn_free(arr);
|
||||
nn_dealloc(alloc, arr, sizeof(nn_array));
|
||||
return nn_values_nil();
|
||||
}
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
@ -62,16 +62,17 @@ nn_value nn_values_array(size_t len) {
|
||||
return (nn_value) {.tag = NN_VALUE_ARRAY, .array = arr};
|
||||
}
|
||||
|
||||
nn_value nn_values_table(size_t pairCount) {
|
||||
nn_table *table = nn_malloc(sizeof(nn_table));
|
||||
nn_value nn_values_table(nn_Alloc *alloc, size_t pairCount) {
|
||||
nn_table *table = nn_alloc(alloc, sizeof(nn_table));
|
||||
if(table == NULL) {
|
||||
return nn_values_nil();
|
||||
}
|
||||
table->alloc = *alloc;
|
||||
table->refc = 1;
|
||||
table->len = pairCount;
|
||||
nn_pair *pairs = nn_malloc(sizeof(nn_pair) * pairCount);
|
||||
nn_pair *pairs = nn_alloc(alloc, sizeof(nn_pair) * pairCount);
|
||||
if(pairs == NULL) {
|
||||
nn_free(table);
|
||||
nn_dealloc(alloc, table, sizeof(nn_table));
|
||||
return nn_values_nil();
|
||||
}
|
||||
for(size_t i = 0; i < pairCount; i++) {
|
||||
@ -101,8 +102,9 @@ void nn_values_drop(nn_value val) {
|
||||
if(val.tag == NN_VALUE_STR) {
|
||||
val.string->refc--;
|
||||
if(val.string->refc == 0) {
|
||||
nn_free(val.string->data);
|
||||
nn_free(val.string);
|
||||
nn_Alloc *a = &val.string->alloc;
|
||||
nn_dealloc(a, val.string->data, val.string->len + 1);
|
||||
nn_dealloc(a, val.string, sizeof(nn_string));
|
||||
}
|
||||
} else if(val.tag == NN_VALUE_ARRAY) {
|
||||
val.array->refc--;
|
||||
@ -110,8 +112,9 @@ void nn_values_drop(nn_value val) {
|
||||
for(size_t i = 0; i < val.array->len; i++) {
|
||||
nn_values_drop(val.array->values[i]);
|
||||
}
|
||||
nn_free(val.array->values);
|
||||
nn_free(val.array);
|
||||
nn_Alloc *a = &val.array->alloc;
|
||||
nn_dealloc(a, val.array->values, sizeof(nn_value) * val.array->len);
|
||||
nn_dealloc(a, val.array, sizeof(nn_array));
|
||||
}
|
||||
} else if(val.tag == NN_VALUE_TABLE) {
|
||||
val.table->refc--;
|
||||
@ -120,8 +123,9 @@ void nn_values_drop(nn_value val) {
|
||||
nn_values_drop(val.table->pairs[i].key);
|
||||
nn_values_drop(val.table->pairs[i].val);
|
||||
}
|
||||
nn_free(val.table->pairs);
|
||||
nn_free(val.table);
|
||||
nn_Alloc *a = &val.table->alloc;
|
||||
nn_dealloc(a, val.table->pairs, sizeof(nn_pair) * val.table->len);
|
||||
nn_dealloc(a, val.table, sizeof(nn_table));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user