5
5
ErrorCaptureStackTrace,
6
6
ObjectPrototypeHasOwnProperty,
7
7
ObjectDefineProperty,
8
- Promise,
9
8
Symbol,
10
9
} = primordials ;
11
10
@@ -53,7 +52,7 @@ const {
53
52
clearAsyncIdStack,
54
53
} = async_wrap ;
55
54
// For performance reasons, only track Promises when a hook is enabled.
56
- const { enablePromiseHook, disablePromiseHook } = async_wrap ;
55
+ const { enablePromiseHook, disablePromiseHook, setPromiseHooks } = async_wrap ;
57
56
// Properties in active_hooks are used to keep track of the set of hooks being
58
57
// executed in case another hook is enabled/disabled. The new set of hooks is
59
58
// then restored once the active set of hooks is finished executing.
@@ -303,71 +302,68 @@ function restoreActiveHooks() {
303
302
active_hooks . tmp_fields = null ;
304
303
}
305
304
306
- function trackPromise ( promise , parent , silent ) {
307
- const asyncId = getOrSetAsyncId ( promise ) ;
305
+ function trackPromise ( promise , parent ) {
306
+ if ( promise [ async_id_symbol ] ) {
307
+ return ;
308
+ }
308
309
310
+ promise [ async_id_symbol ] = newAsyncId ( ) ;
309
311
promise [ trigger_async_id_symbol ] = parent ? getOrSetAsyncId ( parent ) :
310
312
getDefaultTriggerAsyncId ( ) ;
313
+ }
311
314
312
- if ( ! silent && initHooksExist ( ) ) {
313
- const triggerId = promise [ trigger_async_id_symbol ] ;
314
- emitInitScript ( asyncId , 'PROMISE' , triggerId , promise ) ;
315
- }
315
+ function promiseInitHook ( promise , parent ) {
316
+ trackPromise ( promise , parent ) ;
317
+ const asyncId = promise [ async_id_symbol ] ;
318
+ const triggerAsyncId = promise [ trigger_async_id_symbol ] ;
319
+ emitInitScript ( asyncId , 'PROMISE' , triggerAsyncId , promise ) ;
316
320
}
317
321
318
- function fastPromiseHook ( type , promise , parent ) {
319
- if ( type === kInit || ! promise [ async_id_symbol ] ) {
320
- const silent = type !== kInit ;
321
- if ( parent instanceof Promise ) {
322
- trackPromise ( promise , parent , silent ) ;
323
- } else {
324
- trackPromise ( promise , null , silent ) ;
325
- }
322
+ function promiseBeforeHook ( promise ) {
323
+ trackPromise ( promise ) ;
324
+ const asyncId = promise [ async_id_symbol ] ;
325
+ const triggerId = promise [ trigger_async_id_symbol ] ;
326
+ emitBeforeScript ( asyncId , triggerId , promise ) ;
327
+ }
326
328
327
- if ( ! silent ) return ;
329
+ function promiseAfterHook ( promise ) {
330
+ trackPromise ( promise ) ;
331
+ const asyncId = promise [ async_id_symbol ] ;
332
+ if ( hasHooks ( kAfter ) ) {
333
+ emitAfterNative ( asyncId ) ;
328
334
}
335
+ if ( asyncId === executionAsyncId ( ) ) {
336
+ // This condition might not be true if async_hooks was enabled during
337
+ // the promise callback execution.
338
+ // Popping it off the stack can be skipped in that case, because it is
339
+ // known that it would correspond to exactly one call with
340
+ // PromiseHookType::kBefore that was not witnessed by the PromiseHook.
341
+ popAsyncContext ( asyncId ) ;
342
+ }
343
+ }
329
344
345
+ function promiseResolveHook ( promise ) {
346
+ trackPromise ( promise ) ;
330
347
const asyncId = promise [ async_id_symbol ] ;
331
- switch ( type ) {
332
- case kBefore :
333
- const triggerId = promise [ trigger_async_id_symbol ] ;
334
- emitBeforeScript ( asyncId , triggerId , promise ) ;
335
- break ;
336
- case kAfter :
337
- if ( hasHooks ( kAfter ) ) {
338
- emitAfterNative ( asyncId ) ;
339
- }
340
- if ( asyncId === executionAsyncId ( ) ) {
341
- // This condition might not be true if async_hooks was enabled during
342
- // the promise callback execution.
343
- // Popping it off the stack can be skipped in that case, because it is
344
- // known that it would correspond to exactly one call with
345
- // PromiseHookType::kBefore that was not witnessed by the PromiseHook.
346
- popAsyncContext ( asyncId ) ;
347
- }
348
- break ;
349
- case kPromiseResolve :
350
- emitPromiseResolveNative ( asyncId ) ;
351
- break ;
352
- }
348
+ emitPromiseResolveNative ( asyncId ) ;
353
349
}
354
350
355
351
let wantPromiseHook = false ;
356
352
function enableHooks ( ) {
357
353
async_hook_fields [ kCheck ] += 1 ;
358
354
}
359
355
360
- let promiseHookMode = - 1 ;
361
356
function updatePromiseHookMode ( ) {
362
357
wantPromiseHook = true ;
363
358
if ( destroyHooksExist ( ) ) {
364
- if ( promiseHookMode !== 1 ) {
365
- promiseHookMode = 1 ;
366
- enablePromiseHook ( ) ;
367
- }
368
- } else if ( promiseHookMode !== 0 ) {
369
- promiseHookMode = 0 ;
370
- enablePromiseHook ( fastPromiseHook ) ;
359
+ enablePromiseHook ( ) ;
360
+ } else {
361
+ setPromiseHooks (
362
+ initHooksExist ( ) ? promiseInitHook : undefined ,
363
+ promiseBeforeHook ,
364
+ promiseAfterHook ,
365
+ promiseResolveHooksExist ( ) ? promiseResolveHook : undefined ,
366
+ ) ;
371
367
}
372
368
}
373
369
@@ -383,8 +379,8 @@ function disableHooks() {
383
379
384
380
function disablePromiseHookIfNecessary ( ) {
385
381
if ( ! wantPromiseHook ) {
386
- promiseHookMode = - 1 ;
387
382
disablePromiseHook ( ) ;
383
+ setPromiseHooks ( undefined , undefined , undefined , undefined ) ;
388
384
}
389
385
}
390
386
@@ -458,6 +454,10 @@ function destroyHooksExist() {
458
454
return hasHooks ( kDestroy ) ;
459
455
}
460
456
457
+ function promiseResolveHooksExist ( ) {
458
+ return hasHooks ( kPromiseResolve ) ;
459
+ }
460
+
461
461
462
462
function emitInitScript ( asyncId , type , triggerAsyncId , resource ) {
463
463
// Short circuit all checks for the common case. Which is that no hooks have
0 commit comments