@@ -9,7 +9,7 @@ import * as tar from 'tar';
9
9
10
10
import * as api from './api' ;
11
11
import { TOKEN_REF } from './api' ;
12
- import { ObjectTable , tagJsiiConstructor } from './objects' ;
12
+ import { jsiiTypeFqn , ObjectTable , tagJsiiConstructor } from './objects' ;
13
13
import * as onExit from './on-exit' ;
14
14
import * as wire from './serialization' ;
15
15
@@ -19,11 +19,11 @@ export class Kernel {
19
19
*/
20
20
public traceEnabled = false ;
21
21
22
- private assemblies : { [ name : string ] : Assembly } = { } ;
22
+ private readonly assemblies = new Map < string , Assembly > ( ) ;
23
23
private readonly objects = new ObjectTable ( this . _typeInfoForFqn . bind ( this ) ) ;
24
- private cbs : { [ cbid : string ] : Callback } = { } ;
25
- private waiting : { [ cbid : string ] : Callback } = { } ;
26
- private promises : { [ prid : string ] : AsyncInvocation } = { } ;
24
+ private readonly cbs = new Map < string , Callback > ( ) ;
25
+ private readonly waiting = new Map < string , Callback > ( ) ;
26
+ private readonly promises = new Map < string , AsyncInvocation > ( ) ;
27
27
private nextid = 20000 ; // incrementing counter for objid, cbid, promiseid
28
28
private syncInProgress ?: string ; // forbids async calls (begin) while processing sync calls (get/set/invoke)
29
29
private installDir ?: string ;
@@ -86,7 +86,7 @@ export class Kernel {
86
86
87
87
// same version, no-op
88
88
this . _debug ( 'look up already-loaded assembly' , pkgname ) ;
89
- const assm = this . assemblies [ pkgname ] ;
89
+ const assm = this . assemblies . get ( pkgname ) ! ;
90
90
91
91
return {
92
92
assembly : assm . metadata . name ,
@@ -311,19 +311,27 @@ export class Kernel {
311
311
throw new Error ( `${ method } is an async method, use "begin" instead` ) ;
312
312
}
313
313
314
+ const fqn = jsiiTypeFqn ( obj ) ;
314
315
const ret = this . _ensureSync (
315
316
`method '${ objref [ TOKEN_REF ] } .${ method } '` ,
316
317
( ) => {
317
318
return this . _wrapSandboxCode ( ( ) =>
318
- fn . apply ( obj , this . _toSandboxValues ( args , ti . parameters ) ) ,
319
+ fn . apply (
320
+ obj ,
321
+ this . _toSandboxValues (
322
+ args ,
323
+ `method ${ fqn ? `${ fqn } #` : '' } ${ method } ` ,
324
+ ti . parameters ,
325
+ ) ,
326
+ ) ,
319
327
) ;
320
328
} ,
321
329
) ;
322
330
323
331
const result = this . _fromSandbox (
324
332
ret ,
325
333
ti . returns ?? 'void' ,
326
- `returned by method ${ method } ` ,
334
+ `returned by method ${ fqn ? ` ${ fqn } #` : '' } ${ method } ` ,
327
335
) ;
328
336
this . _debug ( 'invoke result' , result ) ;
329
337
@@ -352,7 +360,14 @@ export class Kernel {
352
360
353
361
const ret = this . _ensureSync ( `method '${ fqn } .${ method } '` , ( ) => {
354
362
return this . _wrapSandboxCode ( ( ) =>
355
- fn . apply ( prototype , this . _toSandboxValues ( args , ti . parameters ) ) ,
363
+ fn . apply (
364
+ prototype ,
365
+ this . _toSandboxValues (
366
+ args ,
367
+ `static method ${ fqn } .${ method } ` ,
368
+ ti . parameters ,
369
+ ) ,
370
+ ) ,
356
371
) ;
357
372
} ) ;
358
373
@@ -385,8 +400,17 @@ export class Kernel {
385
400
throw new Error ( `Method ${ method } is expected to be an async method` ) ;
386
401
}
387
402
403
+ const fqn = jsiiTypeFqn ( obj ) ;
404
+
388
405
const promise = this . _wrapSandboxCode ( ( ) =>
389
- fn . apply ( obj , this . _toSandboxValues ( args , ti . parameters ) ) ,
406
+ fn . apply (
407
+ obj ,
408
+ this . _toSandboxValues (
409
+ args ,
410
+ `async method ${ fqn ? `${ fqn } #` : '' } ${ method } ` ,
411
+ ti . parameters ,
412
+ ) ,
413
+ ) ,
390
414
) as Promise < any > ;
391
415
392
416
// since we are planning to resolve this promise in a different scope
@@ -395,10 +419,10 @@ export class Kernel {
395
419
promise . catch ( ( _ ) => undefined ) ;
396
420
397
421
const prid = this . _makeprid ( ) ;
398
- this . promises [ prid ] = {
422
+ this . promises . set ( prid , {
399
423
promise,
400
424
method : ti ,
401
- } ;
425
+ } ) ;
402
426
403
427
return { promiseid : prid } ;
404
428
}
@@ -408,10 +432,11 @@ export class Kernel {
408
432
409
433
this . _debug ( 'end' , promiseid ) ;
410
434
411
- const { promise , method } = this . promises [ promiseid ] ;
412
- if ( promise == null ) {
435
+ const storedPromise = this . promises . get ( promiseid ) ;
436
+ if ( storedPromise == null ) {
413
437
throw new Error ( `Cannot find promise with ID: ${ promiseid } ` ) ;
414
438
}
439
+ const { promise, method } = storedPromise ;
415
440
416
441
let result ;
417
442
try {
@@ -433,9 +458,9 @@ export class Kernel {
433
458
434
459
public callbacks ( _req ?: api . CallbacksRequest ) : api . CallbacksResponse {
435
460
this . _debug ( 'callbacks' ) ;
436
- const ret = Object . keys ( this . cbs ) . map ( ( cbid ) => {
437
- const cb = this . cbs [ cbid ] ;
438
- this . waiting [ cbid ] = cb ; // move to waiting
461
+ const ret = Array . from ( this . cbs . entries ( ) ) . map ( ( [ cbid , cb ] ) => {
462
+ this . waiting . set ( cbid , cb ) ; // move to waiting
463
+ this . cbs . delete ( cbid ) ; // remove from created
439
464
const callback : api . Callback = {
440
465
cbid,
441
466
cookie : cb . override . cookie ,
@@ -448,8 +473,6 @@ export class Kernel {
448
473
return callback ;
449
474
} ) ;
450
475
451
- // move all callbacks to the wait queue and clean the callback queue.
452
- this . cbs = { } ;
453
476
return { callbacks : ret } ;
454
477
}
455
478
@@ -458,25 +481,25 @@ export class Kernel {
458
481
459
482
this . _debug ( 'complete' , cbid , err , result ) ;
460
483
461
- if ( ! ( cbid in this . waiting ) ) {
484
+ const cb = this . waiting . get ( cbid ) ;
485
+ if ( ! cb ) {
462
486
throw new Error ( `Callback ${ cbid } not found` ) ;
463
487
}
464
488
465
- const cb = this . waiting [ cbid ] ;
466
489
if ( err ) {
467
490
this . _debug ( 'completed with error:' , err ) ;
468
491
cb . fail ( new Error ( err ) ) ;
469
492
} else {
470
493
const sandoxResult = this . _toSandbox (
471
494
result ,
472
495
cb . expectedReturnType ?? 'void' ,
473
- `returned by callback ${ cbid } ` ,
496
+ `returned by callback ${ cb . toString ( ) } ` ,
474
497
) ;
475
498
this . _debug ( 'completed with result:' , sandoxResult ) ;
476
499
cb . succeed ( sandoxResult ) ;
477
500
}
478
501
479
- delete this . waiting [ cbid ] ;
502
+ this . waiting . delete ( cbid ) ;
480
503
481
504
return { cbid } ;
482
505
}
@@ -506,7 +529,7 @@ export class Kernel {
506
529
}
507
530
508
531
private _addAssembly ( assm : Assembly ) {
509
- this . assemblies [ assm . metadata . name ] = assm ;
532
+ this . assemblies . set ( assm . metadata . name , assm ) ;
510
533
511
534
// add the __jsii__.fqn property on every constructor. this allows
512
535
// traversing between the javascript and jsii worlds given any object.
@@ -576,7 +599,13 @@ export class Kernel {
576
599
const ctor = ctorResult . ctor ;
577
600
const obj = this . _wrapSandboxCode (
578
601
( ) =>
579
- new ctor ( ...this . _toSandboxValues ( requestArgs , ctorResult . parameters ) ) ,
602
+ new ctor (
603
+ ...this . _toSandboxValues (
604
+ requestArgs ,
605
+ `new ${ fqn } ` ,
606
+ ctorResult . parameters ,
607
+ ) ,
608
+ ) ,
580
609
) ;
581
610
const objref = this . objects . registerObject ( obj , fqn , req . interfaces ?? [ ] ) ;
582
611
@@ -807,6 +836,10 @@ export class Kernel {
807
836
methodInfo : spec . Method ,
808
837
) {
809
838
const methodName = override . method ;
839
+ const fqn = jsiiTypeFqn ( obj ) ;
840
+ const methodContext = `${ methodInfo . async ? 'async ' : '' } method${
841
+ fqn ? `${ fqn } #` : methodName
842
+ } `;
810
843
811
844
if ( methodInfo . async ) {
812
845
// async method override
@@ -816,18 +849,22 @@ export class Kernel {
816
849
writable : false ,
817
850
value : ( ...methodArgs : any [ ] ) => {
818
851
this . _debug ( 'invoke async method override' , override ) ;
819
- const args = this . _toSandboxValues ( methodArgs , methodInfo . parameters ) ;
852
+ const args = this . _toSandboxValues (
853
+ methodArgs ,
854
+ methodContext ,
855
+ methodInfo . parameters ,
856
+ ) ;
820
857
return new Promise < any > ( ( succeed , fail ) => {
821
858
const cbid = this . _makecbid ( ) ;
822
859
this . _debug ( 'adding callback to queue' , cbid ) ;
823
- this . cbs [ cbid ] = {
860
+ this . cbs . set ( cbid , {
824
861
objref,
825
862
override,
826
863
args,
827
864
expectedReturnType : methodInfo . returns ?? 'void' ,
828
865
succeed,
829
866
fail,
830
- } ;
867
+ } ) ;
831
868
} ) ;
832
869
} ,
833
870
} ) ;
@@ -853,7 +890,11 @@ export class Kernel {
853
890
invoke : {
854
891
objref,
855
892
method : methodName ,
856
- args : this . _fromSandboxValues ( methodArgs , methodInfo . parameters ) ,
893
+ args : this . _fromSandboxValues (
894
+ methodArgs ,
895
+ methodContext ,
896
+ methodInfo . parameters ,
897
+ ) ,
857
898
} ,
858
899
} ) ;
859
900
this . _debug ( 'Result' , result ) ;
@@ -936,7 +977,7 @@ export class Kernel {
936
977
}
937
978
938
979
private _assemblyFor ( assemblyName : string ) {
939
- const assembly = this . assemblies [ assemblyName ] ;
980
+ const assembly = this . assemblies . get ( assemblyName ) ;
940
981
if ( ! assembly ) {
941
982
throw new Error ( `Could not find assembly: ${ assemblyName } ` ) ;
942
983
}
@@ -966,7 +1007,7 @@ export class Kernel {
966
1007
const components = fqn . split ( '.' ) ;
967
1008
const moduleName = components [ 0 ] ;
968
1009
969
- const assembly = this . assemblies [ moduleName ] ;
1010
+ const assembly = this . assemblies . get ( moduleName ) ;
970
1011
if ( ! assembly ) {
971
1012
throw new Error ( `Module '${ moduleName } ' not found` ) ;
972
1013
}
@@ -1101,7 +1142,6 @@ export class Kernel {
1101
1142
}
1102
1143
return typeInfo ;
1103
1144
}
1104
-
1105
1145
private _toSandbox (
1106
1146
v : any ,
1107
1147
expectedType : wire . OptionalValueOrVoid ,
@@ -1140,41 +1180,61 @@ export class Kernel {
1140
1180
) ;
1141
1181
}
1142
1182
1143
- private _toSandboxValues ( xs : any [ ] , parameters ?: spec . Parameter [ ] ) {
1144
- return this . _boxUnboxParameters ( xs , parameters , this . _toSandbox . bind ( this ) ) ;
1183
+ private _toSandboxValues (
1184
+ xs : readonly unknown [ ] ,
1185
+ methodContext : string ,
1186
+ parameters : readonly spec . Parameter [ ] | undefined ,
1187
+ ) {
1188
+ return this . _boxUnboxParameters (
1189
+ xs ,
1190
+ methodContext ,
1191
+ parameters ,
1192
+ this . _toSandbox . bind ( this ) ,
1193
+ ) ;
1145
1194
}
1146
1195
1147
- private _fromSandboxValues ( xs : any [ ] , parameters ?: spec . Parameter [ ] ) {
1196
+ private _fromSandboxValues (
1197
+ xs : readonly unknown [ ] ,
1198
+ methodContext : string ,
1199
+ parameters : readonly spec . Parameter [ ] | undefined ,
1200
+ ) {
1148
1201
return this . _boxUnboxParameters (
1149
1202
xs ,
1203
+ methodContext ,
1150
1204
parameters ,
1151
1205
this . _fromSandbox . bind ( this ) ,
1152
1206
) ;
1153
1207
}
1154
1208
1155
1209
private _boxUnboxParameters (
1156
- xs : any [ ] ,
1157
- parameters : spec . Parameter [ ] | undefined ,
1210
+ xs : readonly unknown [ ] ,
1211
+ methodContext : string ,
1212
+ parameters : readonly spec . Parameter [ ] = [ ] ,
1158
1213
boxUnbox : ( x : any , t : wire . OptionalValueOrVoid , context : string ) => any ,
1159
1214
) {
1160
- parameters = [ ...( parameters ?? [ ] ) ] ;
1215
+ const parametersCopy = [ ...parameters ] ;
1161
1216
const variadic =
1162
- parameters . length > 0 && ! ! parameters [ parameters . length - 1 ] . variadic ;
1217
+ parametersCopy . length > 0 &&
1218
+ ! ! parametersCopy [ parametersCopy . length - 1 ] . variadic ;
1163
1219
// Repeat the last (variadic) type to match the number of actual arguments
1164
- while ( variadic && parameters . length < xs . length ) {
1165
- parameters . push ( parameters [ parameters . length - 1 ] ) ;
1220
+ while ( variadic && parametersCopy . length < xs . length ) {
1221
+ parametersCopy . push ( parametersCopy [ parametersCopy . length - 1 ] ) ;
1166
1222
}
1167
- if ( xs . length > parameters . length ) {
1223
+ if ( xs . length > parametersCopy . length ) {
1168
1224
throw new Error (
1169
1225
`Argument list (${ JSON . stringify (
1170
1226
xs ,
1171
1227
) } ) not same size as expected argument list (length ${
1172
- parameters . length
1228
+ parametersCopy . length
1173
1229
} )`,
1174
1230
) ;
1175
1231
}
1176
1232
return xs . map ( ( x , i ) =>
1177
- boxUnbox ( x , parameters ! [ i ] , `of parameter ${ parameters ! [ i ] . name } ` ) ,
1233
+ boxUnbox (
1234
+ x ,
1235
+ parametersCopy [ i ] ,
1236
+ `passed to parameter ${ parametersCopy [ i ] . name } of ${ methodContext } ` ,
1237
+ ) ,
1178
1238
) ;
1179
1239
}
1180
1240
@@ -1225,8 +1285,6 @@ export class Kernel {
1225
1285
* Executes arbitrary code in a VM sandbox.
1226
1286
*
1227
1287
* @param code JavaScript code to be executed in the VM
1228
- * @param sandbox a VM context to use for running the code
1229
- * @param sourceMaps source maps to be used in case an exception is thrown
1230
1288
* @param filename the file name to use for the executed code
1231
1289
*
1232
1290
* @returns the result of evaluating the code
0 commit comments