@@ -29,7 +29,6 @@ using v8::Maybe;
29
29
using v8::MaybeLocal;
30
30
using v8::Nothing;
31
31
using v8::Object;
32
- using v8::ObjectTemplate;
33
32
using v8::SharedArrayBuffer;
34
33
using v8::String;
35
34
using v8::Symbol;
@@ -170,6 +169,20 @@ uint32_t Message::AddWASMModule(CompiledWasmModule&& mod) {
170
169
171
170
namespace {
172
171
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
+
173
186
MaybeLocal<Function> GetDOMException (Local<Context> context) {
174
187
Isolate* isolate = context->GetIsolate ();
175
188
Local<Object> per_context_bindings;
@@ -471,20 +484,31 @@ MessagePort::MessagePort(Environment* env,
471
484
MessagePort* channel = ContainerOf (&MessagePort::async_, handle);
472
485
channel->OnMessage ();
473
486
};
487
+
474
488
CHECK_EQ (uv_async_init (env->event_loop (),
475
489
&async_,
476
490
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
+ });
478
495
479
496
Local<Value> fn;
480
497
if (!wrap->Get (context, env->oninit_symbol ()).ToLocal (&fn))
481
498
return ;
482
499
483
500
if (fn->IsFunction ()) {
484
501
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 ;
486
504
}
487
505
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 );
488
512
Debug (this , " Created message port" );
489
513
}
490
514
@@ -532,6 +556,11 @@ MessagePort* MessagePort::New(
532
556
return nullptr ;
533
557
MessagePort* port = new MessagePort (env, context, instance);
534
558
CHECK_NOT_NULL (port);
559
+ if (port->IsHandleClosing ()) {
560
+ // Construction failed with an exception.
561
+ return nullptr ;
562
+ }
563
+
535
564
if (data) {
536
565
port->Detach ();
537
566
port->data_ = std::move (data);
@@ -624,16 +653,8 @@ void MessagePort::OnMessage() {
624
653
continue ;
625
654
}
626
655
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 ()) {
637
658
// Re-schedule OnMessage() execution in case of failure.
638
659
if (data_)
639
660
TriggerAsync ();
@@ -902,6 +923,7 @@ void MessagePort::Entangle(MessagePort* a, MessagePortData* b) {
902
923
903
924
void MessagePort::MemoryInfo (MemoryTracker* tracker) const {
904
925
tracker->TrackField (" data" , data_);
926
+ tracker->TrackField (" emit_message_fn" , emit_message_fn_);
905
927
}
906
928
907
929
Local<FunctionTemplate> GetMessagePortConstructorTemplate (Environment* env) {
@@ -911,8 +933,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
911
933
if (!templ.IsEmpty ())
912
934
return templ;
913
935
914
- Isolate* isolate = env->isolate ();
915
-
916
936
{
917
937
Local<FunctionTemplate> m = env->NewFunctionTemplate (MessagePort::New);
918
938
m->SetClassName (env->message_port_constructor_string ());
@@ -923,13 +943,6 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
923
943
env->SetProtoMethod (m, " start" , MessagePort::Start);
924
944
925
945
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);
933
946
}
934
947
935
948
return GetMessagePortConstructorTemplate (env);
@@ -948,7 +961,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
948
961
Context::Scope context_scope (context);
949
962
950
963
MessagePort* port1 = MessagePort::New (env, context);
964
+ if (port1 == nullptr ) return ;
951
965
MessagePort* port2 = MessagePort::New (env, context);
966
+ if (port2 == nullptr ) {
967
+ port1->Close ();
968
+ return ;
969
+ }
970
+
952
971
MessagePort::Entangle (port1, port2);
953
972
954
973
args.This ()->Set (context, env->port1_string (), port1->object ())
0 commit comments