-
Notifications
You must be signed in to change notification settings - Fork 126
Open
Description
I've created a repo that you can launch in a Codespaces devcontainer on Github, and have confirmed the error is present there: https://github.com/amoffat/quickjs-bug
Desired behavior
The loop runs successfully, with no errors displayed in the console
Actual behavior
It seems like a signed-integer overflow/wraparound error, and indeed, if the iteration num is lowered to 2^15-1, the error is not present.
Boot up the codespace yourself to fiddle with it, but also here is the minimal application code that causes it. Maybe you can see something obvious?
import VARIANT from "@jitl/quickjs-singlefile-browser-release-sync";
import { newQuickJSWASMModuleFromVariant } from "quickjs-emscripten-core";
async function main() {
console.log("Initializing QuickJS...");
// Fails
const iterations = 2 ** 15;
// Succeeds
// const iterations = 2 ** 15 - 1;
// Initialize QuickJS
const QuickJS = await newQuickJSWASMModuleFromVariant(VARIANT);
const rt = QuickJS.newRuntime();
const vm = rt.newContext();
// Create a dummy host function (necessary to reproduce the bug, but why?)
using dummy = vm.newFunction("dummy", () => {
return vm.newNumber(42);
});
const jsCode = `
async function test() {
return await Promise.resolve(123);
}
`;
// Evaluate the code using QuickJS
vm.evalCode(jsCode).unwrap();
using testHandle = vm.getProp(vm.global, "test");
let i = 0;
for (i = 0; i < iterations; i++) {
using clientPromise = vm.callFunction(testHandle, vm.undefined).unwrap();
// Check promise state and resolve (like the larger project)
const ps = vm.getPromiseState(clientPromise);
if (ps.type === "pending") {
const promise = vm.resolvePromise(clientPromise);
promise.catch((err) => {
const error = vm.dump(err);
console.error("Error in promise:", error);
err.dispose();
});
promise.then((value) => {
value.dispose();
});
} else if (ps.type === "rejected") {
const error = vm.dump(ps.error);
throw new Error("Promise was rejected: " + JSON.stringify(error));
}
rt.executePendingJobs();
}
console.log("Completed iterations:", i);
}
main();Metadata
Metadata
Assignees
Labels
No labels