1
1
'use strict' ;
2
2
3
- const { JSON , Object } = primordials ;
3
+ const { Object } = primordials ;
4
4
5
5
const {
6
6
errnoException,
@@ -55,8 +55,6 @@ const {
55
55
56
56
const { SocketListSend, SocketListReceive } = SocketList ;
57
57
58
- // Lazy loaded for startup performance.
59
- let StringDecoder ;
60
58
// Lazy loaded for startup performance and to allow monkey patching of
61
59
// internalBinding('http_parser').HTTPParser.
62
60
let freeParser ;
@@ -343,6 +341,15 @@ ChildProcess.prototype.spawn = function(options) {
343
341
const ipcFd = stdio . ipcFd ;
344
342
stdio = options . stdio = stdio . stdio ;
345
343
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
+
346
353
if ( ipc !== undefined ) {
347
354
// Let child process know about opened IPC channel
348
355
if ( options . envPairs === undefined )
@@ -353,7 +360,8 @@ ChildProcess.prototype.spawn = function(options) {
353
360
options . envPairs ) ;
354
361
}
355
362
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 } ` ) ;
357
365
}
358
366
359
367
validateString ( options . file , 'options.file' ) ;
@@ -446,7 +454,7 @@ ChildProcess.prototype.spawn = function(options) {
446
454
this . stdio . push ( stdio [ i ] . socket === undefined ? null : stdio [ i ] . socket ) ;
447
455
448
456
// Add .send() method and start listening for IPC data
449
- if ( ipc !== undefined ) setupChannel ( this , ipc ) ;
457
+ if ( ipc !== undefined ) setupChannel ( this , ipc , serialization ) ;
450
458
451
459
return err ;
452
460
} ;
@@ -513,7 +521,8 @@ class Control extends EventEmitter {
513
521
}
514
522
}
515
523
516
- function setupChannel ( target , channel ) {
524
+ let serialization ;
525
+ function setupChannel ( target , channel , serializationMode ) {
517
526
target . channel = channel ;
518
527
519
528
// _channel can be deprecated in version 8
@@ -528,12 +537,16 @@ function setupChannel(target, channel) {
528
537
529
538
const control = new Control ( channel ) ;
530
539
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 ) ;
537
550
channel . pendingHandle = null ;
538
551
channel . onread = function ( arrayBuffer ) {
539
552
const recvHandle = channel . pendingHandle ;
@@ -545,21 +558,7 @@ function setupChannel(target, channel) {
545
558
if ( recvHandle )
546
559
pendingHandle = recvHandle ;
547
560
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 ) ) {
563
562
// There will be at most one NODE_HANDLE message in every chunk we
564
563
// read because SCM_RIGHTS messages don't get coalesced. Make sure
565
564
// that we deliver the handle with the right message however.
@@ -574,9 +573,6 @@ function setupChannel(target, channel) {
574
573
handleMessage ( message , undefined , false ) ;
575
574
}
576
575
}
577
- jsonBuffer = incompleteChunk ;
578
- this . buffering = jsonBuffer . length !== 0 ;
579
-
580
576
} else {
581
577
this . buffering = false ;
582
578
target . disconnect ( ) ;
@@ -775,8 +771,7 @@ function setupChannel(target, channel) {
775
771
776
772
const req = new WriteWrap ( ) ;
777
773
778
- const string = JSON . stringify ( message ) + '\n' ;
779
- const err = channel . writeUtf8String ( req , string , handle ) ;
774
+ const err = writeChannelMessage ( channel , req , message , handle ) ;
780
775
const wasAsyncWrite = streamBaseState [ kLastWriteWasAsync ] ;
781
776
782
777
if ( err === 0 ) {
0 commit comments