better signal semantics and windows mutexes

This commit is contained in:
IonutParau 2026-02-05 16:55:54 +01:00
parent 4a2a60990b
commit 3f39ac27a0
2 changed files with 64 additions and 3 deletions

View File

@ -60,7 +60,7 @@ typedef struct nn_Lock nn_Lock;
#endif
#ifdef NN_WINDOWS
#include <Windows.h>
#include <windows.h>
#endif
#endif
@ -348,7 +348,19 @@ static void nn_defaultLock(void *state, nn_LockRequest *req) {
return;
}
#elif defined(NN_THREAD_WINDOWS)
#error "Windows locks are not supported yet"
switch(req->action) {
case NN_LOCK_CREATE:;
req->lock = CreateMutex(NULL, false, NULL);
case NN_LOCK_DESTROY:;
CloseHandle(req->lock);
return;
case NN_LOCK_LOCK:;
WaitForSingleObject(req->lock, INFINITE);
return;
case NN_LOCK_UNLOCK:;
ReleaseMutex(req->lock);
return;
}
#endif
#endif
@ -1249,6 +1261,41 @@ int nn_countValueCost(nn_Computer *computer, size_t values) {
return total;
}
size_t nn_countSignalCostValue(nn_Value value) {
size_t total = 2;
switch(value.type) {
case NN_VAL_NULL:
case NN_VAL_BOOL:
total += 4;
break;
case NN_VAL_NUM:
case NN_VAL_USERDATA:
total += 8;
break;
case NN_VAL_STR:
// 2+1
if(value.string->len == 0) total++;
else total += value.string->len;
break;
case NN_VAL_TABLE:
total += 2;
for(size_t i = 0; i < value.table->len * 2; i++) {
total += nn_countSignalCostValue(value.table->vals[i]);
}
break;
}
return total;
}
size_t nn_countSignalCost(nn_Computer *computer, size_t values) {
size_t total = 0;
for(size_t i = 0; i < values; i++) {
nn_Value val = computer->callstack[computer->stackSize - values + i];
total += nn_countSignalCostValue(val);
}
return total;
}
size_t nn_countSignals(nn_Computer *computer) {
return computer->signalCount;
}
@ -1258,7 +1305,7 @@ nn_Exit nn_pushSignal(nn_Computer *computer, size_t valueCount) {
if(computer->signalCount == NN_MAX_SIGNALS) return NN_ELIMIT;
if(computer->stackSize < valueCount) return NN_EBELOWSTACK;
int cost = nn_countValueCost(computer, valueCount);
int cost = nn_countSignalCost(computer, valueCount);
if(cost == -1) return NN_EBADSTATE;
if(cost > NN_MAX_SIGNALSIZE) return NN_ELIMIT;

View File

@ -459,8 +459,22 @@ nn_Exit nn_dumptable(nn_Computer *computer, size_t idx, size_t *len);
// computes the cost of the top [values] values using the same algorithm as
// the modem.
// It will return -1 if the values are invalid.
// The algorithm is as mentioned in https://ocdoc.cil.li/component:modem
// and is as follows:
// - Every value adds a 2 byte overhead
// - Numbers add another 8 bytes, true/false/null another 4 bytes, strings as
// many bytes as they contain, except empty strings count as 1 byte.
int nn_countValueCost(nn_Computer *computer, size_t values);
// computes the signal cost.
// This is a slightly modified version of value cost, except it allows
// tables and userdata.
// All values are always valid.
// For userdata and tables:
// - Userdata adds another 8 bytes overhead like numbers do.
// - Tables add yet another 2 byte overhead for their terminator, and the sum of all of the size of the keys and values they contain as per this algorithm.
size_t nn_countSignalCost(nn_Computer *computer, size_t values);
// Returns the amount of signals stored
size_t nn_countSignals(nn_Computer *computer);
// Pops [valueCount] values from the call stack and pushes them as a signal.