2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2023 ,  Andrew  Kaster  < akaster @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ByteReader.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/MemoryStream.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/Socket.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCore/System.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibIPC/Decoder.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibIPC/Encoder.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibIPC/File.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Bindings/ExceptionOrUtils.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-09-25 16:38:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Bindings/Intrinsics.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Bindings/MessagePortPrototype.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/EventDispatcher.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/EventNames.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/MessageEvent.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/MessagePort.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/Scripting/TemporaryExecutionContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/WorkerGlobalScope.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  Web : : HTML  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								constexpr  u8  IPC_FILE_TAG  =  0xA5 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 19:47:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS_DEFINE_ALLOCATOR ( MessagePort ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-13 13:05:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS : : NonnullGCPtr < MessagePort >  MessagePort : : create ( JS : : Realm &  realm )  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-08-13 13:05:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  realm . heap ( ) . allocate < MessagePort > ( realm ,  realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-25 16:38:21 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MessagePort : : MessagePort ( JS : : Realm &  realm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  DOM : : EventTarget ( realm ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								MessagePort : : ~ MessagePort ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    disentangle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-07 08:41:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagePort : : initialize ( JS : : Realm &  realm )  
						 
					
						
							
								
									
										
										
										
											2023-01-10 06:28:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-08-07 08:41:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Base : : initialize ( realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-16 13:13:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    WEB_SET_PROTOTYPE_FOR_INTERFACE ( MessagePort ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-10 06:28:20 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagePort : : visit_edges ( Cell : : Visitor &  visitor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-19 16:18:00 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    visitor . visit ( m_remote_port ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-09 09:20:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: This is incorrect!! We *should* be visiting the worker event target,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //        but CI hangs if we do: https://github.com/SerenityOS/serenity/issues/23899
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    visitor . ignore ( m_worker_event_target ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagePort : : set_worker_event_target ( JS : : NonnullGCPtr < DOM : : EventTarget >  target )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_worker_event_target  =  target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports:transfer-steps
  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								WebIDL : : ExceptionOr < void >  MessagePort : : transfer_steps ( HTML : : TransferDataHolder &  data_holder )  
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Set value's has been shipped flag to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_has_been_shipped  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: 2. Set dataHolder.[[PortMessageQueue]] to value's port message queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Support delivery of messages that haven't been delivered yet on the other side
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. If value is entangled with another port remotePort, then:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_entangled ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 1. Set remotePort's has been shipped flag to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_remote_port - > m_has_been_shipped  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // 2. Set dataHolder.[[RemotePort]] to remotePort.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  fd  =  MUST ( m_socket - > release_fd ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_socket  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-16 13:46:30 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data_holder . fds . append ( IPC : : File : : adopt_fd ( fd ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data_holder . data . append ( IPC_FILE_TAG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 4. Otherwise, set dataHolder.[[RemotePort]] to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data_holder . data . append ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								WebIDL : : ExceptionOr < void >  MessagePort : : transfer_receiving_steps ( HTML : : TransferDataHolder &  data_holder )  
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Set value's has been shipped flag to true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_has_been_shipped  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME 2. Move all the tasks that are to fire message events in dataHolder.[[PortMessageQueue]] to the port message queue of value,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     if any, leaving value's port message queue in its initial disabled state, and, if value's relevant global object is a Window,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     associating the moved tasks with value's relevant global object's associated Document.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 3. If dataHolder.[[RemotePort]] is not null, then entangle dataHolder.[[RemotePort]] and value.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    //     (This will disentangle dataHolder.[[RemotePort]] from the original port that was transferred.)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  fd_tag  =  data_holder . data . take_first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( fd_tag  = =  IPC_FILE_TAG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  fd  =  data_holder . fds . take_first ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-05 00:07:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_socket  =  MUST ( Core : : LocalSocket : : adopt_fd ( fd . take_fd ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_socket - > on_ready_to_read  =  [ strong_this  =  JS : : make_handle ( this ) ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            strong_this - > read_from_socket ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( fd_tag  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln ( " Unexpected byte {:x} in MessagePort transfer data " ,  fd_tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : disentangle ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_remote_port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_remote_port - > m_remote_port  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    m_remote_port  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_socket  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#entangle
  
						 
					
						
							
								
									
										
										
										
											2022-02-17 13:31:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagePort : : entangle_with ( MessagePort &  remote_port )  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_remote_port . ptr ( )  = =  & remote_port ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. If one of the ports is already entangled, then disentangle it and the port that it was entangled with.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_entangled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        disentangle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( remote_port . is_entangled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        remote_port . disentangle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. Associate the two ports to be entangled, so that they form the two parts of a new channel.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //    (There is no MessageChannel object that represents this channel.)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    remote_port . m_remote_port  =  this ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    m_remote_port  =  & remote_port ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  create_paired_sockets  =  [ ] ( )  - >  Array < NonnullOwnPtr < Core : : LocalSocket > ,  2 >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  fds [ 2 ]  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( Core : : System : : socketpair ( AF_LOCAL ,  SOCK_STREAM ,  0 ,  fds ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-05 00:07:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  socket0  =  MUST ( Core : : LocalSocket : : adopt_fd ( fds [ 0 ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( socket0 - > set_blocking ( false ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( socket0 - > set_close_on_exec ( true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-05 00:07:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  socket1  =  MUST ( Core : : LocalSocket : : adopt_fd ( fds [ 1 ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MUST ( socket1 - > set_blocking ( false ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        MUST ( socket1 - > set_close_on_exec ( true ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Array  {  move ( socket0 ) ,  move ( socket1 )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  sockets  =  create_paired_sockets ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_socket  =  move ( sockets [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_remote_port - > m_socket  =  move ( sockets [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_socket - > on_ready_to_read  =  [ strong_this  =  JS : : make_handle ( this ) ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        strong_this - > read_from_socket ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_remote_port - > m_socket - > on_ready_to_read  =  [ remote_port  =  JS : : make_handle ( m_remote_port ) ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        remote_port - > read_from_socket ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage-options
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								WebIDL : : ExceptionOr < void >  MessagePort : : post_message ( JS : : Value  message ,  Vector < JS : : Handle < JS : : Object > >  const &  transfer )  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let targetPort be the port with which this MessagePort is entangled, if any; otherwise let it be null.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    JS : : GCPtr < MessagePort >  target_port  =  m_remote_port ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let options be «[ "transfer" → transfer ]».
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  options  =  StructuredSerializeOptions  {  transfer  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Run the message port post message steps providing this, targetPort, message and options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  message_port_post_message_steps ( target_port ,  message ,  options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-postmessage
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								WebIDL : : ExceptionOr < void >  MessagePort : : post_message ( JS : : Value  message ,  StructuredSerializeOptions  const &  options )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let targetPort be the port with which this MessagePort is entangled, if any; otherwise let it be null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    JS : : GCPtr < MessagePort >  target_port  =  m_remote_port ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Run the message port post message steps providing targetPort, message and options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  message_port_post_message_steps ( target_port ,  message ,  options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#message-port-post-message-steps
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								WebIDL : : ExceptionOr < void >  MessagePort : : message_port_post_message_steps ( JS : : GCPtr < MessagePort >  target_port ,  JS : : Value  message ,  StructuredSerializeOptions  const &  options )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  realm  =  this - > realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  vm  =  this - > vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 1. Let transfer be options["transfer"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const &  transfer  =  options . transfer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. If transfer contains this MessagePort, then throw a "DataCloneError" DOMException.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  const &  handle  :  transfer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( handle  = =  this ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  WebIDL : : DataCloneError : : create ( realm ,  " Cannot transfer a MessagePort to itself " _fly_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let doomed be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  doomed  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. If targetPort is not null and transfer contains targetPort, then set doomed to true and optionally report to a developer console that the target port was posted to itself, causing the communication channel to be lost.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( target_port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  const &  handle  :  transfer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( handle  = =  target_port . ptr ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                doomed  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln ( " FIXME: Report to a developer console that the target port was posted to itself, causing the communication channel to be lost " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 5. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  serialize_with_transfer_result  =  TRY ( structured_serialize_with_transfer ( vm ,  message ,  transfer ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. If targetPort is null, or if doomed is true, then return.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // IMPLEMENTATION DEFINED: Actually check the socket here, not the target port.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //     If there's no target message port in the same realm, we still want to send the message over IPC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_socket  | |  doomed )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 7. Add a task that runs the following steps to the port message queue of targetPort:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    post_port_message ( move ( serialize_with_transfer_result ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < void >  MessagePort : : send_message_on_socket ( SerializedTransferRecord  const &  serialize_with_transfer_result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    IPC : : MessageBuffer  buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    IPC : : Encoder  encoder ( buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MUST ( encoder . encode ( serialize_with_transfer_result ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( buffer . transfer_message ( * m_socket ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : post_port_message ( SerializedTransferRecord  serialize_with_transfer_result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Use the correct task source?
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-16 22:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    queue_global_task ( Task : : Source : : PostedMessage ,  relevant_global_object ( * this ) ,  JS : : create_heap_function ( heap ( ) ,  [ this ,  serialize_with_transfer_result  =  move ( serialize_with_transfer_result ) ] ( )  mutable  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_socket  | |  ! m_socket - > is_open ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  result  =  send_message_on_socket ( serialize_with_transfer_result ) ;  result . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Failed to post message: {} " ,  result . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            disentangle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-16 22:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < MessagePort : : ParseDecision >  MessagePort : : parse_message ( )  
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  constexpr  size_t  HEADER_SIZE  =  sizeof ( u32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  num_bytes_ready  =  m_buffered_data . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_socket_state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SocketState : : Header :  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( num_bytes_ready  <  HEADER_SIZE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ParseDecision : : NotEnoughData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_socket_incoming_message_size  =  ByteReader : : load32 ( m_buffered_data . data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: We don't decrement the number of ready bytes because we want to remove the entire
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       message + header from the buffer in one go on success
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_socket_state  =  SocketState : : Data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [[fallthrough]] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  SocketState : : Data :  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-30 15:04:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( num_bytes_ready  <  HEADER_SIZE  +  m_socket_incoming_message_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  ParseDecision : : NotEnoughData ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  payload  =  m_buffered_data . span ( ) . slice ( HEADER_SIZE ,  m_socket_incoming_message_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        FixedMemoryStream  stream  {  payload ,  FixedMemoryStream : : Mode : : ReadOnly  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        IPC : : Decoder  decoder  {  stream ,  m_unprocessed_fds  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  serialized_transfer_record  =  TRY ( decoder . decode < SerializedTransferRecord > ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-05 14:50:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Make sure to advance our state machine before dispatching the MessageEvent,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // as dispatching events can run arbitrary JS (and cause us to receive another message!)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_socket_state  =  SocketState : : Header ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-05 14:50:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_buffered_data . remove ( 0 ,  HEADER_SIZE  +  m_socket_incoming_message_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        post_message_task_steps ( serialized_transfer_record ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SocketState : : Error : 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-17 16:46:24 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Error : : from_errno ( ENOMSG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ParseDecision : : ParseNextMessage ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : read_from_socket ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    u8  buffer [ 4096 ]  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < int >  fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: What if pending bytes is > 4096? Should we loop here?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  maybe_bytes  =  m_socket - > receive_message ( buffer ,  MSG_NOSIGNAL ,  fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( maybe_bytes . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln ( " MessagePort::read_from_socket(): Failed to receive message: {} " ,  maybe_bytes . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  bytes  =  maybe_bytes . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_buffered_data . append ( bytes . data ( ) ,  bytes . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  fd  :  fds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_unprocessed_fds . enqueue ( IPC : : File : : adopt_fd ( fd ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  parse_decision_or_error  =  parse_message ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( parse_decision_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " MessagePort::read_from_socket(): Failed to parse message: {} " ,  parse_decision_or_error . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( parse_decision_or_error . value ( )  = =  ParseDecision : : NotEnoughData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : post_message_task_steps ( SerializedTransferRecord &  serialize_with_transfer_result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Let finalTargetPort be the MessagePort in whose port message queue the task now finds itself.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: This can be different from targetPort, if targetPort itself was transferred and thus all its tasks moved along with it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  final_target_port  =  this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // IMPLEMENTATION DEFINED:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      Worker objects act as if they had an implicit MessagePort associated with them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      All messages received by that port must immediately be retargeted at the Worker object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // We therefore set a special event target for those implicit ports on the Worker and the WorkerGlobalScope objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    EventTarget *  message_event_target  =  final_target_port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_worker_event_target  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        message_event_target  =  m_worker_event_target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 2. Let targetRealm be finalTargetPort's relevant realm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  target_realm  =  relevant_realm ( * final_target_port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  target_vm  =  target_realm . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 3. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryExecutionContext  context  {  relevant_settings_object ( * final_target_port )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  deserialize_record_or_error  =  structured_deserialize_with_transfer ( target_vm ,  serialize_with_transfer_result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( deserialize_record_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If this throws an exception, catch it, fire an event named messageerror at finalTargetPort, using MessageEvent, and then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  exception  =  deserialize_record_or_error . release_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-01 18:39:03 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        MessageEventInit  event_init  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        message_event_target - > dispatch_event ( MessageEvent : : create ( target_realm ,  HTML : : EventNames : : messageerror ,  event_init ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  deserialize_record  =  deserialize_record_or_error . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // 4. Let messageClone be deserializeRecord.[[Deserialized]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  message_clone  =  deserialize_record . deserialized ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 5. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]], if any, maintaining their relative order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Use a FrozenArray
 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-15 20:58:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < JS : : Handle < MessagePort > >  new_ports ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  object  :  deserialize_record . transferred_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < HTML : : MessagePort > ( * object ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-15 20:58:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            new_ports . append ( verify_cast < MessagePort > ( * object ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-19 15:28:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 6. Fire an event named message at finalTargetPort, using MessageEvent, with the data attribute initialized to messageClone and the ports attribute initialized to newPorts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MessageEventInit  event_init  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    event_init . data  =  message_clone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    event_init . ports  =  move ( new_ports ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-20 13:47:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    message_event_target - > dispatch_event ( MessageEvent : : create ( target_realm ,  HTML : : EventNames : : message ,  event_init ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-start
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : start ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-03-12 10:53:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! is_entangled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-18 17:24:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( m_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO: The start() method steps are to enable this's port message queue, if it is not already enabled.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://html.spec.whatwg.org/multipage/web-messaging.html#dom-messageport-close
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagePort : : close ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 1. Set this MessagePort object's [[Detached]] internal slot value to true.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-07 15:52:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_detached ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // 2. If this MessagePort object is entangled, disentangle it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_entangled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        disentangle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef __ENUMERATE 
  
						 
					
						
							
								
									
										
										
										
											2022-09-24 16:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define __ENUMERATE(attribute_name, event_name)                         \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  MessagePort : : set_ # # attribute_name ( WebIDL : : CallbackType *  value )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {                                                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_event_handler_attribute ( event_name ,  value ) ;                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }                                                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    WebIDL : : CallbackType *  MessagePort : : attribute_name ( )                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {                                                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  event_handler_attribute ( event_name ) ;                      \
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 22:12:31 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS ( __ENUMERATE )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef __ENUMERATE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}