Description
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.