@@ -49,15 +49,18 @@ const init_symbol = Symbol('init');
49
49
const before_symbol = Symbol ( 'before' ) ;
50
50
const after_symbol = Symbol ( 'after' ) ;
51
51
const destroy_symbol = Symbol ( 'destroy' ) ;
52
+ const emitBeforeNative = emitHookFactory ( before_symbol , 'emitBeforeNative' ) ;
53
+ const emitAfterNative = emitHookFactory ( after_symbol , 'emitAfterNative' ) ;
54
+ const emitDestroyNative = emitHookFactory ( destroy_symbol , 'emitDestroyNative' ) ;
52
55
53
56
// Setup the callbacks that node::AsyncWrap will call when there are hooks to
54
57
// process. They use the same functions as the JS embedder API. These callbacks
55
58
// are setup immediately to prevent async_wrap.setupHooks() from being hijacked
56
59
// and the cost of doing so is negligible.
57
60
async_wrap . setupHooks ( { init,
58
- before : emitBeforeN ,
59
- after : emitAfterN ,
60
- destroy : emitDestroyN } ) ;
61
+ before : emitBeforeNative ,
62
+ after : emitAfterNative ,
63
+ destroy : emitDestroyNative } ) ;
61
64
62
65
// Used to fatally abort the process if a callback throws.
63
66
function fatalError ( e ) {
@@ -325,8 +328,8 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
325
328
triggerAsyncId = initTriggerId ( ) ;
326
329
}
327
330
328
- // I'd prefer allowing these checks to not exist, or only throw in a debug
329
- // build, in order to improve performance.
331
+ // TODO(trevnorris): I'd prefer allowing these checks to not exist, or only
332
+ // throw in a debug build, in order to improve performance.
330
333
if ( ! Number . isSafeInteger ( asyncId ) || asyncId < 0 )
331
334
throw new RangeError ( 'asyncId must be an unsigned integer' ) ;
332
335
if ( typeof type !== 'string' || type . length <= 0 )
@@ -342,24 +345,35 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
342
345
}
343
346
}
344
347
345
-
346
- function emitBeforeN ( asyncId ) {
347
- processing_hook = true ;
348
- // Use a single try/catch for all hook to avoid setting up one per iteration.
349
- try {
350
- for ( var i = 0 ; i < active_hooks_array . length ; i ++ ) {
351
- if ( typeof active_hooks_array [ i ] [ before_symbol ] === 'function' ) {
352
- active_hooks_array [ i ] [ before_symbol ] ( asyncId ) ;
348
+ function emitHookFactory ( symbol , name ) {
349
+ // Called from native. The asyncId stack handling is taken care of there
350
+ // before this is called.
351
+ // eslint-disable-next-line func-style
352
+ const fn = function ( asyncId ) {
353
+ processing_hook = true ;
354
+ // Use a single try/catch for all hook to avoid setting up one per
355
+ // iteration.
356
+ try {
357
+ for ( var i = 0 ; i < active_hooks_array . length ; i ++ ) {
358
+ if ( typeof active_hooks_array [ i ] [ symbol ] === 'function' ) {
359
+ active_hooks_array [ i ] [ symbol ] ( asyncId ) ;
360
+ }
353
361
}
362
+ } catch ( e ) {
363
+ fatalError ( e ) ;
354
364
}
355
- } catch ( e ) {
356
- fatalError ( e ) ;
357
- }
358
- processing_hook = false ;
365
+ processing_hook = false ;
359
366
360
- if ( tmp_active_hooks_array !== null ) {
361
- restoreTmpHooks ( ) ;
362
- }
367
+ if ( tmp_active_hooks_array !== null ) {
368
+ restoreTmpHooks ( ) ;
369
+ }
370
+ } ;
371
+ // Set the name property of the anonymous function as it looks good in the
372
+ // stack trace.
373
+ Object . defineProperty ( fn , 'name' , {
374
+ value : name
375
+ } ) ;
376
+ return fn ;
363
377
}
364
378
365
379
@@ -379,29 +393,7 @@ function emitBeforeS(asyncId, triggerAsyncId = asyncId) {
379
393
380
394
if ( async_hook_fields [ kBefore ] === 0 )
381
395
return ;
382
- emitBeforeN ( asyncId ) ;
383
- }
384
-
385
-
386
- // Called from native. The asyncId stack handling is taken care of there before
387
- // this is called.
388
- function emitAfterN ( asyncId ) {
389
- processing_hook = true ;
390
- // Use a single try/catch for all hook to avoid setting up one per iteration.
391
- try {
392
- for ( var i = 0 ; i < active_hooks_array . length ; i ++ ) {
393
- if ( typeof active_hooks_array [ i ] [ after_symbol ] === 'function' ) {
394
- active_hooks_array [ i ] [ after_symbol ] ( asyncId ) ;
395
- }
396
- }
397
- } catch ( e ) {
398
- fatalError ( e ) ;
399
- }
400
- processing_hook = false ;
401
-
402
- if ( tmp_active_hooks_array !== null ) {
403
- restoreTmpHooks ( ) ;
404
- }
396
+ emitBeforeNative ( asyncId ) ;
405
397
}
406
398
407
399
@@ -410,7 +402,7 @@ function emitAfterN(asyncId) {
410
402
// after callbacks.
411
403
function emitAfterS ( asyncId ) {
412
404
if ( async_hook_fields [ kAfter ] > 0 )
413
- emitAfterN ( asyncId ) ;
405
+ emitAfterNative ( asyncId ) ;
414
406
415
407
popAsyncIds ( asyncId ) ;
416
408
}
@@ -425,26 +417,6 @@ function emitDestroyS(asyncId) {
425
417
}
426
418
427
419
428
- function emitDestroyN ( asyncId ) {
429
- processing_hook = true ;
430
- // Use a single try/catch for all hook to avoid setting up one per iteration.
431
- try {
432
- for ( var i = 0 ; i < active_hooks_array . length ; i ++ ) {
433
- if ( typeof active_hooks_array [ i ] [ destroy_symbol ] === 'function' ) {
434
- active_hooks_array [ i ] [ destroy_symbol ] ( asyncId ) ;
435
- }
436
- }
437
- } catch ( e ) {
438
- fatalError ( e ) ;
439
- }
440
- processing_hook = false ;
441
-
442
- if ( tmp_active_hooks_array !== null ) {
443
- restoreTmpHooks ( ) ;
444
- }
445
- }
446
-
447
-
448
420
// Emit callbacks for native calls. Since some state can be setup directly from
449
421
// C++ there's no need to perform all the work here.
450
422
0 commit comments