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} ;
@@ -516,7 +524,8 @@ class Control extends EventEmitter {
516524const channelDeprecationMsg = '_channel is deprecated. ' +
517525 'Use ChildProcess.channel instead.' ;
518526
519- function setupChannel ( target , channel ) {
527+ let serialization ;
528+ function setupChannel ( target , channel , serializationMode ) {
520529 target . channel = channel ;
521530
522531 Object . defineProperty ( target , '_channel' , {
@@ -535,12 +544,16 @@ function setupChannel(target, channel) {
535544
536545 const control = new Control ( channel ) ;
537546
538- if ( StringDecoder === undefined )
539- StringDecoder = require ( 'string_decoder' ) . StringDecoder ;
540- const decoder = new StringDecoder ( 'utf8' ) ;
541- var jsonBuffer = '' ;
542- var pendingHandle = null ;
543- channel . buffering = false ;
547+ if ( serialization === undefined )
548+ serialization = require ( 'internal/child_process/serialization' ) ;
549+ const {
550+ initMessageChannel,
551+ parseChannelMessages,
552+ writeChannelMessage
553+ } = serialization [ serializationMode ] ;
554+
555+ let pendingHandle = null ;
556+ initMessageChannel ( channel ) ;
544557 channel . pendingHandle = null ;
545558 channel . onread = function ( arrayBuffer ) {
546559 const recvHandle = channel . pendingHandle ;
@@ -552,21 +565,7 @@ function setupChannel(target, channel) {
552565 if ( recvHandle )
553566 pendingHandle = recvHandle ;
554567
555- // Linebreak is used as a message end sign
556- var chunks = decoder . write ( pool ) . split ( '\n' ) ;
557- var numCompleteChunks = chunks . length - 1 ;
558- // Last line does not have trailing linebreak
559- var incompleteChunk = chunks [ numCompleteChunks ] ;
560- if ( numCompleteChunks === 0 ) {
561- jsonBuffer += incompleteChunk ;
562- this . buffering = jsonBuffer . length !== 0 ;
563- return ;
564- }
565- chunks [ 0 ] = jsonBuffer + chunks [ 0 ] ;
566-
567- for ( var i = 0 ; i < numCompleteChunks ; i ++ ) {
568- var message = JSON . parse ( chunks [ i ] ) ;
569-
568+ for ( const message of parseChannelMessages ( channel , pool ) ) {
570569 // There will be at most one NODE_HANDLE message in every chunk we
571570 // read because SCM_RIGHTS messages don't get coalesced. Make sure
572571 // that we deliver the handle with the right message however.
@@ -581,9 +580,6 @@ function setupChannel(target, channel) {
581580 handleMessage ( message , undefined , false ) ;
582581 }
583582 }
584- jsonBuffer = incompleteChunk ;
585- this . buffering = jsonBuffer . length !== 0 ;
586-
587583 } else {
588584 this . buffering = false ;
589585 target . disconnect ( ) ;
@@ -782,8 +778,7 @@ function setupChannel(target, channel) {
782778
783779 const req = new WriteWrap ( ) ;
784780
785- const string = JSON . stringify ( message ) + '\n' ;
786- const err = channel . writeUtf8String ( req , string , handle ) ;
781+ const err = writeChannelMessage ( channel , req , message , handle ) ;
787782 const wasAsyncWrite = streamBaseState [ kLastWriteWasAsync ] ;
788783
789784 if ( err === 0 ) {
0 commit comments