diff --git a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime.cpp b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime.cpp index 4e0885764..7196e9fc6 100644 --- a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime.cpp +++ b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime.cpp @@ -3735,14 +3735,7 @@ struct v8_dom_runtime::implementation final { v8::Function::New(local_context, structured_clone, {}, 1).ToLocalChecked()).Check(); install_indexeddb(local_context); install_performance_timeline(local_context); - auto worker_constructor=v8::Function::New(local_context, worker_construct, {}, 1).ToLocalChecked(); - v8::Local event_target,worker_prototype,event_prototype; - if(local_context->Global()->Get(local_context,js_string(isolate,"EventTarget")).ToLocal(&event_target) - &&event_target->IsFunction() - &&worker_constructor->Get(local_context,js_string(isolate,"prototype")).ToLocal(&worker_prototype) - &&event_target.As()->Get(local_context,js_string(isolate,"prototype")).ToLocal(&event_prototype)) - worker_prototype.As()->SetPrototype(local_context,event_prototype).FromMaybe(false); - local_context->Global()->Set(local_context, js_string(isolate, "Worker"),worker_constructor).Check(); + install_worker_constructor(local_context); install_clipboard_api(local_context); install_websocket_globals(local_context); install_editor_web_platform_globals(local_context); diff --git a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_cache_and_frames.inc b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_cache_and_frames.inc index d8412d76b..965bfa763 100644 --- a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_cache_and_frames.inc +++ b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_cache_and_frames.inc @@ -1903,6 +1903,7 @@ install_websocket_globals(local_context); install_editor_web_platform_globals(local_context); install_message_channel(local_context); + install_worker_constructor(local_context); install_tree_walker_platform(local_context); install_custom_elements_platform(local_context); install_fetch_globals(local_context); diff --git a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_workers.inc b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_workers.inc index 5b230a3f4..ef1f927cc 100644 --- a/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_workers.inc +++ b/experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_workers.inc @@ -35,6 +35,35 @@ static constexpr size_t maximum_worker_errors = 16U; static constexpr size_t maximum_worker_error_length = 4096U; + void install_worker_constructor(v8::Local local_context) { + auto worker_constructor = v8::Function::New( + local_context, + worker_construct, + {}, + 1).ToLocalChecked(); + v8::Local event_target; + v8::Local worker_prototype; + v8::Local event_prototype; + if (local_context->Global()->Get( + local_context, + js_string(isolate, "EventTarget")).ToLocal(&event_target) + && event_target->IsFunction() + && worker_constructor->Get( + local_context, + js_string(isolate, "prototype")).ToLocal(&worker_prototype) + && event_target.As()->Get( + local_context, + js_string(isolate, "prototype")).ToLocal(&event_prototype)) { + worker_prototype.As()->SetPrototype( + local_context, + event_prototype).FromMaybe(false); + } + local_context->Global()->Set( + local_context, + js_string(isolate, "Worker"), + worker_constructor).Check(); + } + static v8::MaybeLocal worker_transfer( const v8::FunctionCallbackInfo& info) { if (info.Length() < 2) return v8::Undefined(info.GetIsolate()); @@ -337,6 +366,8 @@ auto realm=child->context.Get(child->isolate);v8::Context::Scope scope(realm); if(packet&&!child->dispatch_worker_message(realm,realm->Global(),&*packet))report(child->last_error); child->drain_tasks(); + child->perform_microtask_checkpoint(); + if (!child->promote_pending_promise_error()) report(child->last_error); } {std::lock_guard lock(raw->mutex);raw->running_isolate=nullptr;} child->isolate->CancelTerminateExecution(); diff --git a/experiments/WebScene.NativeEngine.Probe/tests/hybrid_v8_runtime_tests.cpp b/experiments/WebScene.NativeEngine.Probe/tests/hybrid_v8_runtime_tests.cpp index 6b5273dc8..abd7096ad 100644 --- a/experiments/WebScene.NativeEngine.Probe/tests/hybrid_v8_runtime_tests.cpp +++ b/experiments/WebScene.NativeEngine.Probe/tests/hybrid_v8_runtime_tests.cpp @@ -218,6 +218,9 @@ void test_iframe_worker_extension_host_port_bootstrap() { const child = frame.contentDocument; child.open(); child.write(` diff --git a/tests/WebPlatformSubset/contracts/resources/aureon/iframe-worker-extension-host-module.js b/tests/WebPlatformSubset/contracts/resources/aureon/iframe-worker-extension-host-module.js new file mode 100644 index 000000000..a61ce3148 --- /dev/null +++ b/tests/WebPlatformSubset/contracts/resources/aureon/iframe-worker-extension-host-module.js @@ -0,0 +1,7 @@ +postMessage('worker-started'); +self.onmessage = event => { + const port = event.data.port; + if (!(port instanceof MessagePort)) throw Error('worker port transfer failed'); + port.onmessage = message => port.postMessage(message.data + 1); + port.start(); +}; diff --git a/tests/WebPlatformSubset/webscene-aureon-runtime-profile.json b/tests/WebPlatformSubset/webscene-aureon-runtime-profile.json index 37a6744b2..c04ec0854 100644 --- a/tests/WebPlatformSubset/webscene-aureon-runtime-profile.json +++ b/tests/WebPlatformSubset/webscene-aureon-runtime-profile.json @@ -44,6 +44,17 @@ "reason": "Focused Code OSS iframe bootstrap candidate matching the extension-host MessagePort handoff.", "nativeNavigation": true }, + { + "path": "contracts/iframe-worker-extension-host.html", + "type": "contract", + "capabilities": [ + "iframe-worker-constructor", + "module-workers", + "messageport-transfer" + ], + "reason": "Code OSS-shaped regression proving its hydrated extension-host iframe can construct a module Worker and bridge the transferred bootstrap port.", + "nativeNavigation": true + }, { "path": "contracts/worker-termination-queue-messageerror.html", "type": "contract",