Integer overflow in function IDs
After running a program in QuickJS for a long time, eventually it crashes with this error: QuickJSContext had no callback with id -32768.
-32768 is the minimum int16 value. Looking at this line in context.ts, we see that this error is thrown when this.getFunction(fn_id) returns undefined. Function ids are set by incrementing protected fnNextId: number, starting at -32768.
It seems that after 2^16 function callbacks have been set, the next function ID is 2^16 = 32768, which overflows the int16 used to represent them in C, and gets returned back to JavaScript as -32768. The correct behavior is for context.ts to wrap around to -32768 when allocating the next function id in this line.
newFunction(name: string, fn: VmFunctionImplementation<QuickJSHandle>): QuickJSHandle {
if (this.fnNextId >= (1 << 15)) {
this.fnNextId = -(1 << 15)
}
const fnId = this.fnNextId++ // (is 0 a valid fnId?)
this.setFunction(fnId, fn)
return this.memory.heapValueHandle(this.ffi.QTS_NewFunction(this.ctx.value, fnId, name))
}
Note that I wasn't creating 2^16 functions simultaneously - just cumulative over history. In fact I wasn't actually creating new functions at all, just awaiting promises, which use newFunction internally.
Also ideally we would be able to delete functions from the map when they get disposed... I'm not sure if that's easy, difficult, or impossible.
It should be possible!