@@ -28,7 +28,6 @@ using v8::Maybe;
2828using v8::MaybeLocal;
2929using v8::Nothing;
3030using v8::Object;
31- using v8::ObjectTemplate;
3231using v8::SharedArrayBuffer;
3332using v8::String;
3433using v8::Symbol;
@@ -169,6 +168,20 @@ uint32_t Message::AddWASMModule(WasmModuleObject::TransferrableModule&& mod) {
169168
170169namespace {
171170
171+ MaybeLocal<Function> GetEmitMessageFunction (Local<Context> context) {
172+ Isolate* isolate = context->GetIsolate ();
173+ Local<Object> per_context_bindings;
174+ Local<Value> emit_message_val;
175+ if (!GetPerContextExports (context).ToLocal (&per_context_bindings) ||
176+ !per_context_bindings->Get (context,
177+ FIXED_ONE_BYTE_STRING (isolate, " emitMessage" ))
178+ .ToLocal (&emit_message_val)) {
179+ return MaybeLocal<Function>();
180+ }
181+ CHECK (emit_message_val->IsFunction ());
182+ return emit_message_val.As <Function>();
183+ }
184+
172185MaybeLocal<Function> GetDOMException (Local<Context> context) {
173186 Isolate* isolate = context->GetIsolate ();
174187 Local<Object> per_context_bindings;
@@ -470,20 +483,31 @@ MessagePort::MessagePort(Environment* env,
470483 MessagePort* channel = ContainerOf (&MessagePort::async_, handle);
471484 channel->OnMessage ();
472485 };
486+
473487 CHECK_EQ (uv_async_init (env->event_loop (),
474488 &async_,
475489 onmessage), 0 );
476- async_.data = static_cast <void *>(this );
490+ async_.data = nullptr ; // Reset later to indicate success of the constructor.
491+ auto cleanup = OnScopeLeave ([&]() {
492+ if (async_.data == nullptr ) Close ();
493+ });
477494
478495 Local<Value> fn;
479496 if (!wrap->Get (context, env->oninit_symbol ()).ToLocal (&fn))
480497 return ;
481498
482499 if (fn->IsFunction ()) {
483500 Local<Function> init = fn.As <Function>();
484- USE (init->Call (context, wrap, 0 , nullptr ));
501+ if (init->Call (context, wrap, 0 , nullptr ).IsEmpty ())
502+ return ;
485503 }
486504
505+ Local<Function> emit_message_fn;
506+ if (!GetEmitMessageFunction (context).ToLocal (&emit_message_fn))
507+ return ;
508+ emit_message_fn_.Reset (env->isolate (), emit_message_fn);
509+
510+ async_.data = static_cast <void *>(this );
487511 Debug (this , " Created message port" );
488512}
489513
@@ -531,6 +555,11 @@ MessagePort* MessagePort::New(
531555 return nullptr ;
532556 MessagePort* port = new MessagePort (env, context, instance);
533557 CHECK_NOT_NULL (port);
558+ if (port->IsHandleClosing ()) {
559+ // Construction failed with an exception.
560+ return nullptr ;
561+ }
562+
534563 if (data) {
535564 port->Detach ();
536565 port->data_ = std::move (data);
@@ -623,16 +652,8 @@ void MessagePort::OnMessage() {
623652 continue ;
624653 }
625654
626- Local<Object> event;
627- Local<Value> cb_args[1 ];
628- if (!env ()->message_event_object_template ()->NewInstance (context)
629- .ToLocal (&event) ||
630- event->Set (context, env ()->data_string (), payload).IsNothing () ||
631- event->Set (context, env ()->target_string (), object ()).IsNothing () ||
632- (cb_args[0 ] = event, false ) ||
633- MakeCallback (env ()->onmessage_string (),
634- arraysize (cb_args),
635- cb_args).IsEmpty ()) {
655+ Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
656+ if (MakeCallback (emit_message, 1 , &payload).IsEmpty ()) {
636657 // Re-schedule OnMessage() execution in case of failure.
637658 if (data_)
638659 TriggerAsync ();
@@ -901,6 +922,7 @@ void MessagePort::Entangle(MessagePort* a, MessagePortData* b) {
901922
902923void MessagePort::MemoryInfo (MemoryTracker* tracker) const {
903924 tracker->TrackField (" data" , data_);
925+ tracker->TrackField (" emit_message_fn" , emit_message_fn_);
904926}
905927
906928Local<FunctionTemplate> GetMessagePortConstructorTemplate (Environment* env) {
@@ -910,8 +932,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
910932 if (!templ.IsEmpty ())
911933 return templ;
912934
913- Isolate* isolate = env->isolate ();
914-
915935 {
916936 Local<FunctionTemplate> m = env->NewFunctionTemplate (MessagePort::New);
917937 m->SetClassName (env->message_port_constructor_string ());
@@ -922,13 +942,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
922942 env->SetProtoMethod (m, " start" , MessagePort::Start);
923943
924944 env->set_message_port_constructor_template (m);
925-
926- Local<FunctionTemplate> event_ctor = FunctionTemplate::New (isolate);
927- event_ctor->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " MessageEvent" ));
928- Local<ObjectTemplate> e = event_ctor->InstanceTemplate ();
929- e->Set (env->data_string (), Null (isolate));
930- e->Set (env->target_string (), Null (isolate));
931- env->set_message_event_object_template (e);
932945 }
933946
934947 return GetMessagePortConstructorTemplate (env);
@@ -947,7 +960,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
947960 Context::Scope context_scope (context);
948961
949962 MessagePort* port1 = MessagePort::New (env, context);
963+ if (port1 == nullptr ) return ;
950964 MessagePort* port2 = MessagePort::New (env, context);
965+ if (port2 == nullptr ) {
966+ port1->Close ();
967+ return ;
968+ }
969+
951970 MessagePort::Entangle (port1, port2);
952971
953972 args.This ()->Set (context, env->port1_string (), port1->object ())
0 commit comments