@@ -28,7 +28,6 @@ using v8::Maybe;
28
28
using v8::MaybeLocal;
29
29
using v8::Nothing;
30
30
using v8::Object;
31
- using v8::ObjectTemplate;
32
31
using v8::SharedArrayBuffer;
33
32
using v8::String;
34
33
using v8::Symbol;
@@ -188,6 +187,20 @@ uint32_t Message::AddWASMModule(WasmModuleObject::TransferrableModule&& mod) {
188
187
189
188
namespace {
190
189
190
+ MaybeLocal<Function> GetEmitMessageFunction (Local<Context> context) {
191
+ Isolate* isolate = context->GetIsolate ();
192
+ Local<Object> per_context_bindings;
193
+ Local<Value> emit_message_val;
194
+ if (!GetPerContextExports (context).ToLocal (&per_context_bindings) ||
195
+ !per_context_bindings->Get (context,
196
+ FIXED_ONE_BYTE_STRING (isolate, " emitMessage" ))
197
+ .ToLocal (&emit_message_val)) {
198
+ return MaybeLocal<Function>();
199
+ }
200
+ CHECK (emit_message_val->IsFunction ());
201
+ return emit_message_val.As <Function>();
202
+ }
203
+
191
204
MaybeLocal<Function> GetDOMException (Local<Context> context) {
192
205
Isolate* isolate = context->GetIsolate ();
193
206
Local<Object> per_context_bindings;
@@ -498,20 +511,31 @@ MessagePort::MessagePort(Environment* env,
498
511
MessagePort* channel = ContainerOf (&MessagePort::async_, handle);
499
512
channel->OnMessage ();
500
513
};
514
+
501
515
CHECK_EQ (uv_async_init (env->event_loop (),
502
516
&async_,
503
517
onmessage), 0 );
504
- async_.data = static_cast <void *>(this );
518
+ async_.data = nullptr ; // Reset later to indicate success of the constructor.
519
+ auto cleanup = OnScopeLeave ([&]() {
520
+ if (async_.data == nullptr ) Close ();
521
+ });
505
522
506
523
Local<Value> fn;
507
524
if (!wrap->Get (context, env->oninit_symbol ()).ToLocal (&fn))
508
525
return ;
509
526
510
527
if (fn->IsFunction ()) {
511
528
Local<Function> init = fn.As <Function>();
512
- USE (init->Call (context, wrap, 0 , nullptr ));
529
+ if (init->Call (context, wrap, 0 , nullptr ).IsEmpty ())
530
+ return ;
513
531
}
514
532
533
+ Local<Function> emit_message_fn;
534
+ if (!GetEmitMessageFunction (context).ToLocal (&emit_message_fn))
535
+ return ;
536
+ emit_message_fn_.Reset (env->isolate (), emit_message_fn);
537
+
538
+ async_.data = static_cast <void *>(this );
515
539
Debug (this , " Created message port" );
516
540
}
517
541
@@ -559,6 +583,11 @@ MessagePort* MessagePort::New(
559
583
return nullptr ;
560
584
MessagePort* port = new MessagePort (env, context, instance);
561
585
CHECK_NOT_NULL (port);
586
+ if (port->IsHandleClosing ()) {
587
+ // Construction failed with an exception.
588
+ return nullptr ;
589
+ }
590
+
562
591
if (data) {
563
592
port->Detach ();
564
593
port->data_ = std::move (data);
@@ -651,16 +680,8 @@ void MessagePort::OnMessage() {
651
680
continue ;
652
681
}
653
682
654
- Local<Object> event;
655
- Local<Value> cb_args[1 ];
656
- if (!env ()->message_event_object_template ()->NewInstance (context)
657
- .ToLocal (&event) ||
658
- event->Set (context, env ()->data_string (), payload).IsNothing () ||
659
- event->Set (context, env ()->target_string (), object ()).IsNothing () ||
660
- (cb_args[0 ] = event, false ) ||
661
- MakeCallback (env ()->onmessage_string (),
662
- arraysize (cb_args),
663
- cb_args).IsEmpty ()) {
683
+ Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
684
+ if (MakeCallback (emit_message, 1 , &payload).IsEmpty ()) {
664
685
// Re-schedule OnMessage() execution in case of failure.
665
686
if (data_)
666
687
TriggerAsync ();
@@ -929,6 +950,7 @@ void MessagePort::Entangle(MessagePort* a, MessagePortData* b) {
929
950
930
951
void MessagePort::MemoryInfo (MemoryTracker* tracker) const {
931
952
tracker->TrackField (" data" , data_);
953
+ tracker->TrackField (" emit_message_fn" , emit_message_fn_);
932
954
}
933
955
934
956
Local<FunctionTemplate> GetMessagePortConstructorTemplate (Environment* env) {
@@ -938,8 +960,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
938
960
if (!templ.IsEmpty ())
939
961
return templ;
940
962
941
- Isolate* isolate = env->isolate ();
942
-
943
963
{
944
964
Local<FunctionTemplate> m = env->NewFunctionTemplate (MessagePort::New);
945
965
m->SetClassName (env->message_port_constructor_string ());
@@ -950,13 +970,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
950
970
env->SetProtoMethod (m, " start" , MessagePort::Start);
951
971
952
972
env->set_message_port_constructor_template (m);
953
-
954
- Local<FunctionTemplate> event_ctor = FunctionTemplate::New (isolate);
955
- event_ctor->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " MessageEvent" ));
956
- Local<ObjectTemplate> e = event_ctor->InstanceTemplate ();
957
- e->Set (env->data_string (), Null (isolate));
958
- e->Set (env->target_string (), Null (isolate));
959
- env->set_message_event_object_template (e);
960
973
}
961
974
962
975
return GetMessagePortConstructorTemplate (env);
@@ -975,7 +988,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
975
988
Context::Scope context_scope (context);
976
989
977
990
MessagePort* port1 = MessagePort::New (env, context);
991
+ if (port1 == nullptr ) return ;
978
992
MessagePort* port2 = MessagePort::New (env, context);
993
+ if (port2 == nullptr ) {
994
+ port1->Close ();
995
+ return ;
996
+ }
997
+
979
998
MessagePort::Entangle (port1, port2);
980
999
981
1000
args.This ()->Set (context, env->port1_string (), port1->object ())
0 commit comments