@@ -29,7 +29,6 @@ using v8::Maybe;
2929using v8::MaybeLocal;
3030using v8::Nothing;
3131using v8::Object;
32- using v8::ObjectTemplate;
3332using v8::SharedArrayBuffer;
3433using v8::String;
3534using v8::Symbol;
@@ -170,6 +169,20 @@ uint32_t Message::AddWASMModule(CompiledWasmModule&& mod) {
170169
171170namespace {
172171
172+ MaybeLocal<Function> GetEmitMessageFunction (Local<Context> context) {
173+ Isolate* isolate = context->GetIsolate ();
174+ Local<Object> per_context_bindings;
175+ Local<Value> emit_message_val;
176+ if (!GetPerContextExports (context).ToLocal (&per_context_bindings) ||
177+ !per_context_bindings->Get (context,
178+ FIXED_ONE_BYTE_STRING (isolate, " emitMessage" ))
179+ .ToLocal (&emit_message_val)) {
180+ return MaybeLocal<Function>();
181+ }
182+ CHECK (emit_message_val->IsFunction ());
183+ return emit_message_val.As <Function>();
184+ }
185+
173186MaybeLocal<Function> GetDOMException (Local<Context> context) {
174187 Isolate* isolate = context->GetIsolate ();
175188 Local<Object> per_context_bindings;
@@ -471,20 +484,31 @@ MessagePort::MessagePort(Environment* env,
471484 MessagePort* channel = ContainerOf (&MessagePort::async_, handle);
472485 channel->OnMessage ();
473486 };
487+
474488 CHECK_EQ (uv_async_init (env->event_loop (),
475489 &async_,
476490 onmessage), 0 );
477- async_.data = static_cast <void *>(this );
491+ async_.data = nullptr ; // Reset later to indicate success of the constructor.
492+ auto cleanup = OnScopeLeave ([&]() {
493+ if (async_.data == nullptr ) Close ();
494+ });
478495
479496 Local<Value> fn;
480497 if (!wrap->Get (context, env->oninit_symbol ()).ToLocal (&fn))
481498 return ;
482499
483500 if (fn->IsFunction ()) {
484501 Local<Function> init = fn.As <Function>();
485- USE (init->Call (context, wrap, 0 , nullptr ));
502+ if (init->Call (context, wrap, 0 , nullptr ).IsEmpty ())
503+ return ;
486504 }
487505
506+ Local<Function> emit_message_fn;
507+ if (!GetEmitMessageFunction (context).ToLocal (&emit_message_fn))
508+ return ;
509+ emit_message_fn_.Reset (env->isolate (), emit_message_fn);
510+
511+ async_.data = static_cast <void *>(this );
488512 Debug (this , " Created message port" );
489513}
490514
@@ -532,6 +556,11 @@ MessagePort* MessagePort::New(
532556 return nullptr ;
533557 MessagePort* port = new MessagePort (env, context, instance);
534558 CHECK_NOT_NULL (port);
559+ if (port->IsHandleClosing ()) {
560+ // Construction failed with an exception.
561+ return nullptr ;
562+ }
563+
535564 if (data) {
536565 port->Detach ();
537566 port->data_ = std::move (data);
@@ -624,16 +653,8 @@ void MessagePort::OnMessage() {
624653 continue ;
625654 }
626655
627- Local<Object> event;
628- Local<Value> cb_args[1 ];
629- if (!env ()->message_event_object_template ()->NewInstance (context)
630- .ToLocal (&event) ||
631- event->Set (context, env ()->data_string (), payload).IsNothing () ||
632- event->Set (context, env ()->target_string (), object ()).IsNothing () ||
633- (cb_args[0 ] = event, false ) ||
634- MakeCallback (env ()->onmessage_string (),
635- arraysize (cb_args),
636- cb_args).IsEmpty ()) {
656+ Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
657+ if (MakeCallback (emit_message, 1 , &payload).IsEmpty ()) {
637658 // Re-schedule OnMessage() execution in case of failure.
638659 if (data_)
639660 TriggerAsync ();
@@ -902,6 +923,7 @@ void MessagePort::Entangle(MessagePort* a, MessagePortData* b) {
902923
903924void MessagePort::MemoryInfo (MemoryTracker* tracker) const {
904925 tracker->TrackField (" data" , data_);
926+ tracker->TrackField (" emit_message_fn" , emit_message_fn_);
905927}
906928
907929Local<FunctionTemplate> GetMessagePortConstructorTemplate (Environment* env) {
@@ -911,8 +933,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
911933 if (!templ.IsEmpty ())
912934 return templ;
913935
914- Isolate* isolate = env->isolate ();
915-
916936 {
917937 Local<FunctionTemplate> m = env->NewFunctionTemplate (MessagePort::New);
918938 m->SetClassName (env->message_port_constructor_string ());
@@ -923,13 +943,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
923943 env->SetProtoMethod (m, " start" , MessagePort::Start);
924944
925945 env->set_message_port_constructor_template (m);
926-
927- Local<FunctionTemplate> event_ctor = FunctionTemplate::New (isolate);
928- event_ctor->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " MessageEvent" ));
929- Local<ObjectTemplate> e = event_ctor->InstanceTemplate ();
930- e->Set (env->data_string (), Null (isolate));
931- e->Set (env->target_string (), Null (isolate));
932- env->set_message_event_object_template (e);
933946 }
934947
935948 return GetMessagePortConstructorTemplate (env);
@@ -948,7 +961,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
948961 Context::Scope context_scope (context);
949962
950963 MessagePort* port1 = MessagePort::New (env, context);
964+ if (port1 == nullptr ) return ;
951965 MessagePort* port2 = MessagePort::New (env, context);
966+ if (port2 == nullptr ) {
967+ port1->Close ();
968+ return ;
969+ }
970+
952971 MessagePort::Entangle (port1, port2);
953972
954973 args.This ()->Set (context, env->port1_string (), port1->object ())
0 commit comments