huge progress on filesystem

This commit is contained in:
IonutParau 2025-05-28 23:19:08 +02:00
parent c3ebf82981
commit 7daf034d25
6 changed files with 194 additions and 15 deletions

View File

@ -62,6 +62,7 @@ pub fn build(b: *std.Build) void {
});
emulator.linkLibC();
emulator.linkSystemLibrary("lua");
emulator.linkSystemLibrary("raylib");
emulator.addCSourceFiles(.{
.files = &.{
"src/testLuaArch.c",

View File

@ -98,6 +98,15 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu
nn_setCError(computer, "out of space");
return;
}
if(buf == NULL) {
if(data.tag == NN_VALUE_NIL) {
buf = "";
len = 0;
} else {
nn_setCError(computer, "bad data (string expected)");
return;
}
}
eeprom->set(component, eeprom->userdata, buf, len);
nn_eepromControl control = nn_eeprom_getControl(component, eeprom);
@ -132,8 +141,17 @@ void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c
void nn_eeprom_setData(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) {
nn_value data = nn_getArgument(computer, 0);
size_t len;
size_t len = 0;
const char *buf = nn_toString(data, &len);
if(buf == NULL) {
if(data.tag == NN_VALUE_NIL) {
buf = "";
len = 0;
} else {
nn_setCError(computer, "bad data (string expected)");
return;
}
}
if(len > eeprom->getDataSize(component, eeprom->userdata)) {
nn_setCError(computer, "out of space");
return;

View File

@ -1,4 +1,5 @@
#include "../neonucleus.h"
#include <stdio.h>
#include <string.h>
void nn_fs_destroy(void *_, nn_component *component, nn_filesystem *fs) {
@ -266,7 +267,7 @@ void nn_fs_list(nn_filesystem *fs, void *_, nn_component *component, nn_computer
// operation succeeded
nn_value arr = nn_values_array(fileCount);
for(size_t i = 0; i < fileCount; i++) {
nn_values_set(arr, i, nn_values_cstring(files[i]));
nn_values_set(arr, i, nn_values_string(files[i], strlen(files[i])));
nn_free(files[i]);
}
nn_free(files);
@ -336,7 +337,7 @@ void nn_fs_write(nn_filesystem *fs, void *_, nn_component *component, nn_compute
void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) {
nn_value fdValue = nn_getArgument(computer, 0);
size_t fd = nn_toInt(fdValue);
int fd = nn_toInt(fdValue);
nn_value lenValue = nn_getArgument(computer, 1);
double len = nn_toNumber(lenValue);
@ -423,6 +424,5 @@ void nn_loadFilesystemTable(nn_universe *universe) {
nn_component *nn_addFileSystem(nn_computer *computer, nn_address address, int slot, nn_filesystem *filesystem) {
nn_componentTable *fsTable = nn_queryUserdata(nn_getUniverse(computer), "NN:FILESYSTEM");
return nn_newComponent(computer, address, slot, fsTable, filesystem);
}

View File

@ -1,9 +1,11 @@
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "neonucleus.h"
#include "testLuaArch.h"
#include <raylib.h>
nn_eepromControl ne_eeprom_getControl(nn_component *component, void *_) {
return (nn_eepromControl) {
@ -69,6 +71,126 @@ bool ne_eeprom_isReadonly(nn_component *component, void *userdata) {
void ne_eeprom_makeReadonly(nn_component *component, void *userdata) {}
#define NE_FS_MAX 128
typedef struct ne_fs {
FILE *files[NE_FS_MAX];
size_t fileLen;
} ne_fs;
nn_filesystemControl ne_fs_getControl(nn_component *component, ne_fs *_) {
return (nn_filesystemControl) {
.pretendChunkSize = 512,
.pretendRPM = 1800,
.writeHeatPerChunk = 0.01,
.writeCostPerChunk = 3,
.writeEnergyCost = 0.015,
.writeLatencyPerChunk = 0.0003,
.readEnergyCost = 0.007,
.readCostPerChunk = 1,
.readLatencyPerChunk = 0.0001,
.randomLatencyMin = 0.0005,
.randomLatencyMax = 0.0019,
.seekCostPerChunk = 1,
.motorHeat = 0.03,
.motorEnergyCost = 0.5,
};
}
size_t ne_fs_spaceUsed(nn_component *component, void *_) {
return 0; // ultra accurate
}
size_t ne_fs_spaceTotal(nn_component *component, void *_) {
return 1*1024*1024;
}
const char *ne_fs_diskPath(nn_component *component, const char *path) {
static char buf[256];
const char *root = ne_location(nn_getComponentAddress(component));
if(path[0] == '/') {
snprintf(buf, 256, "%s%s", root, path);
} else {
snprintf(buf, 256, "%s/%s", root, path);
}
return buf;
}
size_t ne_fs_open(nn_component *component, ne_fs *fs, const char *path, const char *mode) {
if(fs->fileLen == NE_FS_MAX) {
nn_setCError(nn_getComputerOfComponent(component), "too many files");
return 0;
}
const char *trueMode = "rb";
if(strcmp(mode, "w") == 0) {
trueMode = "wb";
}
if(strcmp(mode, "a") == 0) {
trueMode = "ab";
}
const char *p = ne_fs_diskPath(component, path);
FILE *f = fopen(p, trueMode);
if(f == NULL) {
nn_setCError(nn_getComputerOfComponent(component), strerror(errno));
return 0;
}
for(size_t i = 0; i < fs->fileLen; i++) {
if(fs->files[i] == NULL) {
fs->files[i] = f;
return i;
}
}
size_t i = fs->fileLen++;
fs->files[i] = f;
return i;
}
bool ne_fs_close(nn_component *component, ne_fs *fs, int fd) {
// we pray
fclose(fs->files[fd]);
fs->files[fd] = NULL;
return true;
}
bool ne_fs_write(nn_component *component, ne_fs *fs, int fd, const char *buf, size_t len) {
FILE *f = fs->files[fd];
return fwrite(buf, sizeof(char), len, f) > 0;
}
size_t ne_fs_read(nn_component *component, ne_fs *fs, int fd, char *buf, size_t required) {
FILE *f = fs->files[fd];
if(feof(f)) return 0;
return fread(buf, sizeof(char), required, f);
}
char **ne_fs_list(nn_component *component, ne_fs *fs, const char *path, size_t *len) {
const char *p = ne_fs_diskPath(component, path);
FilePathList files = LoadDirectoryFiles(p);
*len = files.count;
char **buf = nn_malloc(sizeof(char *) * files.count);
for(size_t i = 0; i < files.count; i++) {
buf[i] = nn_strdup(GetFileName(files.paths[i]));
}
UnloadDirectoryFiles(files);
return buf;
}
bool ne_fs_isDirectory(nn_component *component, ne_fs *fs, const char *path) {
const char *p = ne_fs_diskPath(component, path);
return DirectoryExists(p);
}
int main() {
printf("Setting up universe\n");
nn_universe *universe = nn_newUniverse();
@ -80,6 +202,7 @@ int main() {
// 1MB of RAM, 16 components max
nn_computer *computer = nn_newComputer(universe, "testMachine", arch, NULL, 1*1024*1024, 16);
nn_setEnergyInfo(computer, 5000, 5000);
nn_setCallBudget(computer, 18000);
nn_addSupportedArchitecture(computer, arch);
nn_eeprom genericEEPROM = {
@ -101,6 +224,37 @@ int main() {
nn_addEeprom(computer, "luaBios.lua", 0, &genericEEPROM);
ne_fs fs = {
.files = {NULL},
.fileLen = 0,
};
nn_filesystem genericFS = {
.refc = 0,
.userdata = &fs,
.deinit = NULL,
.control = (void *)ne_fs_getControl,
.getLabel = ne_eeprom_getLabel,
.setLabel = ne_eeprom_setLabel,
.spaceUsed = ne_fs_spaceUsed,
.spaceTotal = ne_fs_spaceTotal,
.isReadOnly = ne_eeprom_isReadonly,
.size = NULL,
.remove = NULL,
.lastModified = NULL,
.rename = NULL,
.exists = NULL,
.isDirectory = (void *)ne_fs_isDirectory,
.makeDirectory = NULL,
.list = (void *)ne_fs_list,
.open = (void *)ne_fs_open,
.close = (void *)ne_fs_close,
.write = (void *)ne_fs_write,
.read = (void *)ne_fs_read,
.seek = NULL,
};
nn_addFileSystem(computer, "OpenOS", 1, &genericFS);
double lastTime = nn_realTime();
while(true) {
double now = nn_realTime();
@ -116,6 +270,9 @@ int main() {
}
int state = nn_tickComputer(computer);
if(nn_isOverworked(computer)) {
printf("Machine overworked.\n");
}
if(state == NN_STATE_SWITCH) {
nn_architecture *nextArch = nn_getNextArchitecture(computer);
printf("Next architecture: %s\n", nextArch->archName);

View File

@ -390,9 +390,11 @@ sandbox = {
},
utf8 = copy(utf8),
unicode = copy(unicode),
checkArg = checkArg,
component = libcomponent,
computer = libcomputer,
print = print,
}
sandbox._G = sandbox
@ -418,12 +420,10 @@ while true do
local ok, err = resume(co)
if not ok then
error(err)
error(debug.traceback(co, err), 0)
elseif coroutine.status(co) == "dead" then
error("computer halted", 0)
else
coroutine.yield()
end
end
error("machine halted")

View File

@ -19,14 +19,12 @@ void *testLuaArch_alloc(testLuaArch *arch, void *ptr, size_t osize, size_t nsize
nn_free(ptr);
return NULL;
} else {
if(arch->memoryUsed - osize + nsize > nn_getComputerMemoryTotal(arch->computer)) {
size_t actualOldSize = osize;
if(ptr == NULL) actualOldSize = 0;
if(arch->memoryUsed - actualOldSize + nsize > nn_getComputerMemoryTotal(arch->computer)) {
return NULL; // OOM condition
}
if(ptr != NULL) {
// if ptr is NULL, osize will actually encode the type.
// We do not want that to mess us up.
arch->memoryUsed -= osize;
}
arch->memoryUsed -= actualOldSize;
arch->memoryUsed += nsize;
return nn_realloc(ptr, nsize);
}
@ -397,8 +395,9 @@ static int testLuaArch_component_invoke(lua_State *L) {
return 2;
}
nn_resetCall(c);
printf("%s %s %d\n", addr, method, argc);
for(size_t i = 0; i < argc; i++) {
nn_addArgument(c, testLuaArch_getValue(L, 2 + argc));
nn_addArgument(c, testLuaArch_getValue(L, 3 + i));
}
if(!nn_invokeComponentMethod(component, method)) {
nn_resetCall(c);
@ -500,6 +499,10 @@ void testLuaArch_loadEnv(lua_State *L) {
lua_pushinteger(L, NN_STATE_SWITCH);
lua_setfield(L, states, "switch");
lua_setglobal(L, "states");
lua_createtable(L, 0, 20);
int unicode = lua_gettop(L);
lua_setglobal(L, "unicode");
}
testLuaArch *testLuaArch_setup(nn_computer *computer, void *_) {