@@ -126,11 +126,18 @@ class DeserializerDelegate : public ValueDeserializer::Delegate {
126
126
} // anonymous namespace
127
127
128
128
MaybeLocal<Value> Message::Deserialize (Environment* env,
129
- Local<Context> context) {
129
+ Local<Context> context,
130
+ Local<Value>* port_list) {
131
+ Context::Scope context_scope (context);
132
+
130
133
CHECK (!IsCloseMessage ());
134
+ if (port_list != nullptr && !transferables_.empty ()) {
135
+ // Need to create this outside of the EscapableHandleScope, but inside
136
+ // the Context::Scope.
137
+ *port_list = Array::New (env->isolate ());
138
+ }
131
139
132
140
EscapableHandleScope handle_scope (env->isolate ());
133
- Context::Scope context_scope (context);
134
141
135
142
// Create all necessary objects for transferables, e.g. MessagePort handles.
136
143
std::vector<BaseObjectPtr<BaseObject>> host_objects (transferables_.size ());
@@ -146,10 +153,27 @@ MaybeLocal<Value> Message::Deserialize(Environment* env,
146
153
});
147
154
148
155
for (uint32_t i = 0 ; i < transferables_.size (); ++i) {
156
+ HandleScope handle_scope (env->isolate ());
149
157
TransferData* data = transferables_[i].get ();
150
158
host_objects[i] = data->Deserialize (
151
159
env, context, std::move (transferables_[i]));
152
160
if (!host_objects[i]) return {};
161
+ if (port_list != nullptr ) {
162
+ // If we gather a list of all message ports, and this transferred object
163
+ // is a message port, add it to that list. This is a bit of an odd case
164
+ // of special handling for MessagePorts (as opposed to applying to all
165
+ // transferables), but it's required for spec compliancy.
166
+ DCHECK ((*port_list)->IsArray ());
167
+ Local<Array> port_list_array = port_list->As <Array>();
168
+ Local<Object> obj = host_objects[i]->object ();
169
+ if (env->message_port_constructor_template ()->HasInstance (obj)) {
170
+ if (port_list_array->Set (context,
171
+ port_list_array->Length (),
172
+ obj).IsNothing ()) {
173
+ return {};
174
+ }
175
+ }
176
+ }
153
177
}
154
178
transferables_.clear ();
155
179
@@ -664,7 +688,8 @@ MessagePort* MessagePort::New(
664
688
}
665
689
666
690
MaybeLocal<Value> MessagePort::ReceiveMessage (Local<Context> context,
667
- MessageProcessingMode mode) {
691
+ MessageProcessingMode mode,
692
+ Local<Value>* port_list) {
668
693
std::shared_ptr<Message> received;
669
694
{
670
695
// Get the head of the message queue.
@@ -696,7 +721,7 @@ MaybeLocal<Value> MessagePort::ReceiveMessage(Local<Context> context,
696
721
697
722
if (!env ()->can_call_into_js ()) return MaybeLocal<Value>();
698
723
699
- return received->Deserialize (env (), context);
724
+ return received->Deserialize (env (), context, port_list );
700
725
}
701
726
702
727
void MessagePort::OnMessage (MessageProcessingMode mode) {
@@ -735,14 +760,15 @@ void MessagePort::OnMessage(MessageProcessingMode mode) {
735
760
Local<Function> emit_message = PersistentToLocal::Strong (emit_message_fn_);
736
761
737
762
Local<Value> payload;
763
+ Local<Value> port_list = Undefined (env ()->isolate ());
738
764
Local<Value> message_error;
739
- Local<Value> argv[2 ];
765
+ Local<Value> argv[3 ];
740
766
741
767
{
742
768
// Catch any exceptions from parsing the message itself (not from
743
769
// emitting it) as 'messageeror' events.
744
770
TryCatchScope try_catch (env ());
745
- if (!ReceiveMessage (context, mode).ToLocal (&payload)) {
771
+ if (!ReceiveMessage (context, mode, &port_list ).ToLocal (&payload)) {
746
772
if (try_catch.HasCaught () && !try_catch.HasTerminated ())
747
773
message_error = try_catch.Exception ();
748
774
goto reschedule;
@@ -757,13 +783,15 @@ void MessagePort::OnMessage(MessageProcessingMode mode) {
757
783
}
758
784
759
785
argv[0 ] = payload;
760
- argv[1 ] = env ()->message_string ();
786
+ argv[1 ] = port_list;
787
+ argv[2 ] = env ()->message_string ();
761
788
762
789
if (MakeCallback (emit_message, arraysize (argv), argv).IsEmpty ()) {
763
790
reschedule:
764
791
if (!message_error.IsEmpty ()) {
765
792
argv[0 ] = message_error;
766
- argv[1 ] = env ()->messageerror_string ();
793
+ argv[1 ] = Undefined (env ()->isolate ());
794
+ argv[2 ] = env ()->messageerror_string ();
767
795
USE (MakeCallback (emit_message, arraysize (argv), argv));
768
796
}
769
797
0 commit comments