11'use strict' ;
22
3- const { JSON , Object } = primordials ;
3+ const { Object } = primordials ;
44
55const {
66 errnoException,
@@ -55,8 +55,6 @@ const {
5555
5656const { SocketListSend, SocketListReceive } = SocketList ;
5757
58- // Lazy loaded for startup performance.
59- let StringDecoder ;
6058// Lazy loaded for startup performance and to allow monkey patching of
6159// internalBinding('http_parser').HTTPParser.
6260let freeParser ;
@@ -343,6 +341,15 @@ ChildProcess.prototype.spawn = function(options) {
343341 const ipcFd = stdio . ipcFd ;
344342 stdio = options . stdio = stdio . stdio ;
345343
344+ if ( options . serialization !== undefined &&
345+ options . serialization !== 'json' &&
346+ options . serialization !== 'advanced' ) {
347+ throw new ERR_INVALID_OPT_VALUE ( 'options.serialization' ,
348+ options . serialization ) ;
349+ }
350+
351+ const serialization = options . serialization || 'json' ;
352+
346353 if ( ipc !== undefined ) {
347354 // Let child process know about opened IPC channel
348355 if ( options . envPairs === undefined )
@@ -353,7 +360,8 @@ ChildProcess.prototype.spawn = function(options) {
353360 options . envPairs ) ;
354361 }
355362
356- options . envPairs . push ( 'NODE_CHANNEL_FD=' + ipcFd ) ;
363+ options . envPairs . push ( `NODE_CHANNEL_FD=${ ipcFd } ` ) ;
364+ options . envPairs . push ( `NODE_CHANNEL_SERIALIZATION_MODE=${ serialization } ` ) ;
357365 }
358366
359367 validateString ( options . file , 'options.file' ) ;
@@ -446,7 +454,7 @@ ChildProcess.prototype.spawn = function(options) {
446454 this . stdio . push ( stdio [ i ] . socket === undefined ? null : stdio [ i ] . socket ) ;
447455
448456 // Add .send() method and start listening for IPC data
449- if ( ipc !== undefined ) setupChannel ( this , ipc ) ;
457+ if ( ipc !== undefined ) setupChannel ( this , ipc , serialization ) ;
450458
451459 return err ;
452460} ;
@@ -513,7 +521,8 @@ class Control extends EventEmitter {
513521 }
514522}
515523
516- function setupChannel ( target , channel ) {
524+ let serialization ;
525+ function setupChannel ( target , channel , serializationMode ) {
517526 target . channel = channel ;
518527
519528 // _channel can be deprecated in version 8
@@ -528,12 +537,16 @@ function setupChannel(target, channel) {
528537
529538 const control = new Control ( channel ) ;
530539
531- if ( StringDecoder === undefined )
532- StringDecoder = require ( 'string_decoder' ) . StringDecoder ;
533- const decoder = new StringDecoder ( 'utf8' ) ;
534- var jsonBuffer = '' ;
535- var pendingHandle = null ;
536- channel . buffering = false ;
540+ if ( serialization === undefined )
541+ serialization = require ( 'internal/child_process/serialization' ) ;
542+ const {
543+ initMessageChannel,
544+ parseChannelMessages,
545+ writeChannelMessage
546+ } = serialization [ serializationMode ] ;
547+
548+ let pendingHandle = null ;
549+ initMessageChannel ( channel ) ;
537550 channel . pendingHandle = null ;
538551 channel . onread = function ( arrayBuffer ) {
539552 const recvHandle = channel . pendingHandle ;
@@ -545,21 +558,7 @@ function setupChannel(target, channel) {
545558 if ( recvHandle )
546559 pendingHandle = recvHandle ;
547560
548- // Linebreak is used as a message end sign
549- var chunks = decoder . write ( pool ) . split ( '\n' ) ;
550- var numCompleteChunks = chunks . length - 1 ;
551- // Last line does not have trailing linebreak
552- var incompleteChunk = chunks [ numCompleteChunks ] ;
553- if ( numCompleteChunks === 0 ) {
554- jsonBuffer += incompleteChunk ;
555- this . buffering = jsonBuffer . length !== 0 ;
556- return ;
557- }
558- chunks [ 0 ] = jsonBuffer + chunks [ 0 ] ;
559-
560- for ( var i = 0 ; i < numCompleteChunks ; i ++ ) {
561- var message = JSON . parse ( chunks [ i ] ) ;
562-
561+ for ( const message of parseChannelMessages ( channel , pool ) ) {
563562 // There will be at most one NODE_HANDLE message in every chunk we
564563 // read because SCM_RIGHTS messages don't get coalesced. Make sure
565564 // that we deliver the handle with the right message however.
@@ -574,9 +573,6 @@ function setupChannel(target, channel) {
574573 handleMessage ( message , undefined , false ) ;
575574 }
576575 }
577- jsonBuffer = incompleteChunk ;
578- this . buffering = jsonBuffer . length !== 0 ;
579-
580576 } else {
581577 this . buffering = false ;
582578 target . disconnect ( ) ;
@@ -775,8 +771,7 @@ function setupChannel(target, channel) {
775771
776772 const req = new WriteWrap ( ) ;
777773
778- const string = JSON . stringify ( message ) + '\n' ;
779- const err = channel . writeUtf8String ( req , string , handle ) ;
774+ const err = writeChannelMessage ( channel , req , message , handle ) ;
780775 const wasAsyncWrite = streamBaseState [ kLastWriteWasAsync ] ;
781776
782777 if ( err === 0 ) {
0 commit comments