diff --git a/NativeScript/runtime/Worker.mm b/NativeScript/runtime/Worker.mm index 47f6bd20..d4223994 100644 --- a/NativeScript/runtime/Worker.mm +++ b/NativeScript/runtime/Worker.mm @@ -744,6 +744,9 @@ throw NativeScriptException( void Worker::OnMessageCallback(Isolate* isolate, Local receiver, std::shared_ptr message) { + // Callers drain a whole batch under one scope; without this the handles of + // every message in the batch stay alive until the batch ends. + HandleScope handleScope(isolate); WorkerEventsState* state = Caches::StateFor(isolate); if (state == nullptr || state->emitMessage.IsEmpty()) { return; diff --git a/TestRunner/app/tests/MessagingTests.js b/TestRunner/app/tests/MessagingTests.js index ff30cbe8..bcaa8ac0 100644 --- a/TestRunner/app/tests/MessagingTests.js +++ b/TestRunner/app/tests/MessagingTests.js @@ -155,10 +155,11 @@ describe("Messaging runtime edges", function () { var got = []; worker.on("message", function (value) { got.push(value); - if (got.length === 3) { + if (got.length === 4) { setTimeout(function () { - // Three messages: the once() registration fires only - // for the first, the on() one for all three. + // Three messages: the on() registration fires for all + // three, the once() one only for the first. The settle + // window catches a fifth reply. expect(got).toEqual([1, 2, 3, 4]); worker.terminate(); done(); diff --git a/TestRunner/app/tests/RuntimeImplementedAPIs.js b/TestRunner/app/tests/RuntimeImplementedAPIs.js index 6df75d6c..df563e60 100644 --- a/TestRunner/app/tests/RuntimeImplementedAPIs.js +++ b/TestRunner/app/tests/RuntimeImplementedAPIs.js @@ -83,9 +83,12 @@ describe("DOMException canary", () => { }); it("serializes through structuredClone on this runtime", () => { - const clone = structuredClone(new DOMException("x", "AbortError")); + const original = new DOMException("x", "AbortError"); + original.stack = "DOMException stack sentinel"; + const clone = structuredClone(original); expect(clone instanceof DOMException).toBe(true); expect(clone.name).toBe("AbortError"); + expect(clone.stack).toBe("DOMException stack sentinel"); }); // Once an isolate holds a DOMException the serializer claims host objects