made it work better for GC languages

This commit is contained in:
2026-07-06 17:00:32 +02:00
parent 5f06a5659c
commit 37b348ef13
3 changed files with 73 additions and 1 deletions

View File

@@ -792,7 +792,7 @@ static void luaArch_loadEnv(lua_State *L) {
static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) { static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) {
nn_Computer *computer = req->computer; nn_Computer *computer = req->computer;
luaArch *arch = req->localState; luaArch *arch = req->localState;
nn_Context *ctx = nn_getComputerContext(computer); nn_Context *ctx = computer == NULL ? NULL : nn_getComputerContext(computer);
// the memory scale, used to give Lua extra memory in 64-bit systems // the memory scale, used to give Lua extra memory in 64-bit systems
// due to it also using more memory. // due to it also using more memory.
double memScale = sizeof(void *) > 4 ? 1.8 : 1; double memScale = sizeof(void *) > 4 ? 1.8 : 1;
@@ -857,6 +857,10 @@ static nn_Exit luaArch_handler(nn_ArchitectureRequest *req) {
case NN_ARCH_DESERIALIZE: case NN_ARCH_DESERIALIZE:
// do nothing // do nothing
return NN_OK; return NN_OK;
case NN_ARCH_RETAIN:
return NN_OK;
case NN_ARCH_DROP:
return NN_OK;
} }
return NN_OK; return NN_OK;
} }

View File

@@ -1229,6 +1229,8 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char
c->signalCount = 0; c->signalCount = 0;
c->userCount = 0; c->userCount = 0;
c->idleTimestamp = 0; c->idleTimestamp = 0;
c->arch.handler = NULL;
c->desiredArch.handler = NULL;
// set to empty string // set to empty string
c->errorBuffer[0] = '\0'; c->errorBuffer[0] = '\0';
for(size_t i = 0; i < NN_MAX_USERDATA; i++) c->uservals[i].state = NULL; for(size_t i = 0; i < NN_MAX_USERDATA; i++) c->uservals[i].state = NULL;
@@ -1314,9 +1316,29 @@ bool nn_isComputerOn(nn_Computer *computer) {
} }
void nn_setComputerEnvironment(nn_Computer *computer, nn_Environment env) { void nn_setComputerEnvironment(nn_Computer *computer, nn_Environment env) {
nn_retainComputerEnvironment(env);
nn_dropComputerEnvironment(computer->env);
computer->env = env; computer->env = env;
} }
void nn_retainComputerEnvironment(nn_Environment env) {
if(env.handler == NULL) return;
nn_EnvironmentRequest req;
req.userdata = env.userdata;
req.computer = NULL;
req.action = NN_ENV_RETAIN;
env.handler(&req);
}
void nn_dropComputerEnvironment(nn_Environment env) {
if(env.handler == NULL) return;
nn_EnvironmentRequest req;
req.userdata = env.userdata;
req.computer = NULL;
req.action = NN_ENV_DROP;
env.handler(&req);
}
void nn_setDirectCost(nn_Computer *computer, double directCost) { void nn_setDirectCost(nn_Computer *computer, double directCost) {
computer->directCost = directCost; computer->directCost = directCost;
} }
@@ -1465,6 +1487,12 @@ void nn_destroyComputerN(nn_Computer *computer, size_t n) {
for(size_t i = 0; i < computer->userCount; i++) { for(size_t i = 0; i < computer->userCount; i++) {
nn_strfree(ctx, computer->users[i]); nn_strfree(ctx, computer->users[i]);
} }
nn_dropArchitecture(computer->arch);
for(size_t i = 0; i < computer->archCount; i++) {
nn_dropArchitecture(computer->archs[i]);
}
nn_dropComputerEnvironment(computer->env);
for(size_t i = 0; i < NN_MAX_USERDATA; i++) nn_freeUserdata(computer, i); for(size_t i = 0; i < NN_MAX_USERDATA; i++) nn_freeUserdata(computer, i);
@@ -1571,6 +1599,8 @@ bool nn_hasUser(nn_Computer *computer, const char *user) {
} }
void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch) { void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch) {
nn_retainArchitecture(*arch);
nn_dropArchitecture(computer->arch);
computer->arch = *arch; computer->arch = *arch;
} }
@@ -1578,7 +1608,29 @@ nn_Architecture nn_getArchitecture(nn_Computer *computer) {
return computer->arch; return computer->arch;
} }
void nn_retainArchitecture(nn_Architecture arch) {
if(arch.handler == NULL) return;
nn_ArchitectureRequest req;
req.computer = NULL;
req.action = NN_ARCH_RETAIN;
req.globalState = arch.state;
req.localState = NULL;
arch.handler(&req);
}
void nn_dropArchitecture(nn_Architecture arch) {
if(arch.handler == NULL) return;
nn_ArchitectureRequest req;
req.computer = NULL;
req.action = NN_ARCH_DROP;
req.globalState = arch.state;
req.localState = NULL;
arch.handler(&req);
}
void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch) { void nn_setDesiredArchitecture(nn_Computer *computer, const nn_Architecture *arch) {
nn_retainArchitecture(*arch);
nn_dropArchitecture(computer->desiredArch);
computer->desiredArch = *arch; computer->desiredArch = *arch;
} }
@@ -1588,6 +1640,7 @@ nn_Architecture nn_getDesiredArchitecture(nn_Computer *computer) {
nn_Exit nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch) { nn_Exit nn_addSupportedArchitecture(nn_Computer *computer, const nn_Architecture *arch) {
if(computer->archCount == NN_MAX_ARCHITECTURES) return NN_ELIMIT; if(computer->archCount == NN_MAX_ARCHITECTURES) return NN_ELIMIT;
nn_retainArchitecture(*arch);
computer->archs[computer->archCount++] = *arch; computer->archs[computer->archCount++] = *arch;
return NN_OK; return NN_OK;
} }

View File

@@ -354,6 +354,10 @@ typedef enum nn_ArchitectureAction {
NN_ARCH_DESERIALIZE, NN_ARCH_DESERIALIZE,
// serialize to an encoded state, pushed it as a string // serialize to an encoded state, pushed it as a string
NN_ARCH_SERIALIZE, NN_ARCH_SERIALIZE,
// information about usage, for GC languages to know when it is safe to reclaim references.
// computer and localState are both NULL when these are emitted.
NN_ARCH_RETAIN,
NN_ARCH_DROP,
} nn_ArchitectureAction; } nn_ArchitectureAction;
typedef struct nn_ArchitectureRequest { typedef struct nn_ArchitectureRequest {
@@ -423,6 +427,9 @@ typedef enum nn_EnvironmentAction {
NN_ENV_CRASHED, NN_ENV_CRASHED,
NN_ENV_BEEP, NN_ENV_BEEP,
NN_ENV_BEEPMORSE, NN_ENV_BEEPMORSE,
// information about usage, for GC languages to know when it is safe to reclaim references
NN_ENV_RETAIN,
NN_ENV_DROP,
} nn_EnvironmentAction; } nn_EnvironmentAction;
typedef struct nn_EnvironmentRequest { typedef struct nn_EnvironmentRequest {
@@ -473,6 +480,8 @@ void nn_forceCrashComputer(nn_Computer *computer, const char *s);
// returns whether an architecture state is present // returns whether an architecture state is present
bool nn_isComputerOn(nn_Computer *computer); bool nn_isComputerOn(nn_Computer *computer);
void nn_setComputerEnvironment(nn_Computer *computer, nn_Environment env); void nn_setComputerEnvironment(nn_Computer *computer, nn_Environment env);
void nn_retainComputerEnvironment(nn_Environment env);
void nn_dropComputerEnvironment(nn_Environment env);
void nn_setDirectCost(nn_Computer *computer, double directCost); void nn_setDirectCost(nn_Computer *computer, double directCost);
double nn_getDirectCost(nn_Computer *computer); double nn_getDirectCost(nn_Computer *computer);
@@ -601,6 +610,12 @@ bool nn_hasUser(nn_Computer *computer, const char *user);
void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch); void nn_setArchitecture(nn_Computer *computer, const nn_Architecture *arch);
// Gets the current architecture. // Gets the current architecture.
nn_Architecture nn_getArchitecture(nn_Computer *computer); nn_Architecture nn_getArchitecture(nn_Computer *computer);
// Notify the architecture it is being retained. This is to help GC'd languages that provide architectures know
// when the garbage collector can safely reclaim the memory again.
void nn_retainArchitecture(nn_Architecture arch);
// Notify the architecture it is being dropped. This is to help GC'd languages that provide architectures know
// when the garbage collector can safely reclaim the memory again.
void nn_dropArchitecture(nn_Architecture arch);
// Sets the computer's desired architecture. // Sets the computer's desired architecture.
// The desired architecture indicates, when the computer state is CHARCH, what the new architecture should be. // The desired architecture indicates, when the computer state is CHARCH, what the new architecture should be.
// This is set even if it is not in the supported architecture list, *you must check if it is in that list first.* // This is set even if it is not in the supported architecture list, *you must check if it is in that list first.*