@@ -9662,6 +9662,63 @@ test "parallel_js: TypedArray set snapshots array-like source length under no-GI
96629662 try std.testing.expect(result.asBool());
96639663}
96649664
9665+ test "parallel_js: mapped arguments severing is atomic under no-GIL readers" {
9666+ if (builtin.single_threaded) return error.SkipZigTest;
9667+ const ctx = try Context.createWithTestingOptions(std.testing.allocator, .{
9668+ .enable_threads = true,
9669+ .enable_gc = true,
9670+ .parallel_gc = true,
9671+ .parallel_js = true,
9672+ });
9673+ defer ctx.destroy();
9674+
9675+ const result = try ctx.evaluate(
9676+ \\(() => {
9677+ \\ if ($vm.useThreadGIL() !== false)
9678+ \\ throw new Error("main still holds the thread GIL");
9679+ \\ function mint(a, b, c) { return arguments; }
9680+ \\ const shared = { slot: null, stop: 0, started: 0, go: 0 };
9681+ \\ const sentinel = "value-one";
9682+ \\ const readers = [];
9683+ \\ for (let r = 0; r < 2; ++r) {
9684+ \\ readers.push(new Thread((shared, sentinel) => {
9685+ \\ if ($vm.useThreadGIL() !== false)
9686+ \\ throw new Error("worker still holds the thread GIL");
9687+ \\ Atomics.add(shared, "started", 1);
9688+ \\ while (Atomics.load(shared, "go") === 0)
9689+ \\ Atomics.wait(shared, "go", 0, 100);
9690+ \\ let failures = 0;
9691+ \\ while (Atomics.load(shared, "stop") === 0) {
9692+ \\ const args = shared.slot;
9693+ \\ if (args === null) continue;
9694+ \\ if (args[1] !== sentinel) ++failures;
9695+ \\ const v0 = args[0];
9696+ \\ if (!(v0 === 7 || v0 === undefined)) ++failures;
9697+ \\ const len = args.length;
9698+ \\ if (!(len === 3 || len === 99)) ++failures;
9699+ \\ }
9700+ \\ return failures;
9701+ \\ }, shared, sentinel));
9702+ \\ }
9703+ \\ while (Atomics.load(shared, "started") !== readers.length)
9704+ \\ Atomics.wait(shared, "started", Atomics.load(shared, "started"), 100);
9705+ \\ Atomics.store(shared, "go", 1);
9706+ \\ Atomics.notify(shared, "go", readers.length);
9707+ \\ for (let i = 0; i < 750; ++i) {
9708+ \\ const args = mint(7, sentinel, true);
9709+ \\ shared.slot = args;
9710+ \\ delete args[0];
9711+ \\ args.length = 99;
9712+ \\ if ((i & 31) === 0) Atomics.wait(shared, "go", 1, 1);
9713+ \\ }
9714+ \\ Atomics.store(shared, "stop", 1);
9715+ \\ Atomics.notify(shared, "stop", readers.length);
9716+ \\ return readers.every(t => t.join() === 0);
9717+ \\})()
9718+ );
9719+ try std.testing.expect(result.asBool());
9720+ }
9721+
96659722test "TypedArray set coerces offset before detached buffer checks" {
96669723 try std.testing.expect((try evalIn(
96679724 \\class ExpectedError extends Error {}
0 commit comments