@@ -14,18 +14,18 @@ const {
1414
1515const  {  internalBinding }  =  require ( 'internal/bootstrap/loaders' ) ; 
1616const  {  MessagePort,  MessageChannel }  =  internalBinding ( 'messaging' ) ; 
17- const  {  handle_onclose }  =  internalBinding ( 'symbols' ) ; 
17+ const  { 
18+   handle_onclose : handleOnCloseSymbol , 
19+   oninit : onInitSymbol 
20+ }  =  internalBinding ( 'symbols' ) ; 
1821const  {  clearAsyncIdStack }  =  require ( 'internal/async_hooks' ) ; 
1922const  {  serializeError,  deserializeError }  =  require ( 'internal/error-serdes' ) ; 
2023const  {  pathToFileURL }  =  require ( 'url' ) ; 
2124
22- util . inherits ( MessagePort ,  EventEmitter ) ; 
23- 
2425const  { 
2526  Worker : WorkerImpl , 
2627  getEnvMessagePort, 
27-   threadId, 
28-   oninit : oninit_symbol 
28+   threadId
2929}  =  internalBinding ( 'worker' ) ; 
3030
3131const  isMainThread  =  threadId  ===  0 ; 
@@ -58,6 +58,23 @@ const messageTypes = {
5858  LOAD_SCRIPT : 'loadScript' 
5959} ; 
6060
61+ // We have to mess with the MessagePort prototype a bit, so that a) we can make 
62+ // it inherit from EventEmitter, even though it is a C++ class, and b) we do 
63+ // not provide methods that are not present in the Browser and not documented 
64+ // on our side (e.g. hasRef). 
65+ // Save a copy of the original set of methods as a shallow clone. 
66+ const  MessagePortPrototype  =  Object . create ( 
67+   Object . getPrototypeOf ( MessagePort . prototype ) , 
68+   Object . getOwnPropertyDescriptors ( MessagePort . prototype ) ) ; 
69+ // Set up the new inheritance chain. 
70+ Object . setPrototypeOf ( MessagePort ,  EventEmitter ) ; 
71+ Object . setPrototypeOf ( MessagePort . prototype ,  EventEmitter . prototype ) ; 
72+ // Finally, purge methods we don't want to be public. 
73+ delete  MessagePort . prototype . stop ; 
74+ delete  MessagePort . prototype . drain ; 
75+ delete  MessagePort . prototype . hasRef ; 
76+ delete  MessagePort . prototype . getAsyncId ; 
77+ 
6178// A communication channel consisting of a handle (that wraps around an 
6279// uv_async_t) which can receive information from other threads and emits 
6380// .onmessage events, and a function used for sending data to a MessagePort 
@@ -81,10 +98,10 @@ Object.defineProperty(MessagePort.prototype, 'onmessage', {
8198    this [ kOnMessageListener ]  =  value ; 
8299    if  ( typeof  value  ===  'function' )  { 
83100      this . ref ( ) ; 
84-       this . start ( ) ; 
101+       MessagePortPrototype . start . call ( this ) ; 
85102    }  else  { 
86103      this . unref ( ) ; 
87-       this . stop ( ) ; 
104+       MessagePortPrototype . stop . call ( this ) ; 
88105    } 
89106  } 
90107} ) ; 
@@ -94,7 +111,7 @@ function oninit() {
94111  setupPortReferencing ( this ,  this ,  'message' ) ; 
95112} 
96113
97- Object . defineProperty ( MessagePort . prototype ,  oninit_symbol ,  { 
114+ Object . defineProperty ( MessagePort . prototype ,  onInitSymbol ,  { 
98115  enumerable : true , 
99116  writable : false , 
100117  value : oninit 
@@ -111,22 +128,18 @@ function onclose() {
111128  this . emit ( 'close' ) ; 
112129} 
113130
114- Object . defineProperty ( MessagePort . prototype ,  handle_onclose ,  { 
131+ Object . defineProperty ( MessagePort . prototype ,  handleOnCloseSymbol ,  { 
115132  enumerable : false , 
116133  writable : false , 
117134  value : onclose 
118135} ) ; 
119136
120- const  originalClose  =  MessagePort . prototype . close ; 
121137MessagePort . prototype . close  =  function ( cb )  { 
122138  if  ( typeof  cb  ===  'function' ) 
123139    this . once ( 'close' ,  cb ) ; 
124-   originalClose . call ( this ) ; 
140+   MessagePortPrototype . close . call ( this ) ; 
125141} ; 
126142
127- const  drainMessagePort  =  MessagePort . prototype . drain ; 
128- delete  MessagePort . prototype . drain ; 
129- 
130143Object . defineProperty ( MessagePort . prototype ,  util . inspect . custom ,  { 
131144  enumerable : false , 
132145  writable : false , 
@@ -135,7 +148,7 @@ Object.defineProperty(MessagePort.prototype, util.inspect.custom, {
135148    try  { 
136149      // This may throw when `this` does not refer to a native object, 
137150      // e.g. when accessing the prototype directly. 
138-       ref  =  this . hasRef ( ) ; 
151+       ref  =  MessagePortPrototype . hasRef . call ( this ) ; 
139152    }  catch  {  return  this ;  } 
140153    return  Object . assign ( Object . create ( MessagePort . prototype ) , 
141154                         ref  ===  undefined  ? { 
@@ -157,12 +170,12 @@ function setupPortReferencing(port, eventEmitter, eventName) {
157170  eventEmitter . on ( 'newListener' ,  ( name )  =>  { 
158171    if  ( name  ===  eventName  &&  eventEmitter . listenerCount ( eventName )  ===  0 )  { 
159172      port . ref ( ) ; 
160-       port . start ( ) ; 
173+       MessagePortPrototype . start . call ( port ) ; 
161174    } 
162175  } ) ; 
163176  eventEmitter . on ( 'removeListener' ,  ( name )  =>  { 
164177    if  ( name  ===  eventName  &&  eventEmitter . listenerCount ( eventName )  ===  0 )  { 
165-       port . stop ( ) ; 
178+       MessagePortPrototype . stop . call ( port ) ; 
166179      port . unref ( ) ; 
167180    } 
168181  } ) ; 
@@ -304,7 +317,7 @@ class Worker extends EventEmitter {
304317
305318  [ kOnExit ] ( code )  { 
306319    debug ( `[${ threadId } ${ this . threadId }  ) ; 
307-     drainMessagePort . call ( this [ kPublicPort ] ) ; 
320+     MessagePortPrototype . drain . call ( this [ kPublicPort ] ) ; 
308321    this [ kDispose ] ( ) ; 
309322    this . emit ( 'exit' ,  code ) ; 
310323    this . removeAllListeners ( ) ; 
0 commit comments