55 ErrorCaptureStackTrace,
66 ObjectPrototypeHasOwnProperty,
77 ObjectDefineProperty,
8- Promise,
98 Symbol,
109} = primordials ;
1110
@@ -53,7 +52,7 @@ const {
5352 clearAsyncIdStack,
5453} = async_wrap ;
5554// For performance reasons, only track Promises when a hook is enabled.
56- const { enablePromiseHook, disablePromiseHook } = async_wrap ;
55+ const { enablePromiseHook, disablePromiseHook, setPromiseHooks } = async_wrap ;
5756// Properties in active_hooks are used to keep track of the set of hooks being
5857// executed in case another hook is enabled/disabled. The new set of hooks is
5958// then restored once the active set of hooks is finished executing.
@@ -303,71 +302,68 @@ function restoreActiveHooks() {
303302 active_hooks . tmp_fields = null ;
304303}
305304
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+ }
308309
310+ promise [ async_id_symbol ] = newAsyncId ( ) ;
309311 promise [ trigger_async_id_symbol ] = parent ? getOrSetAsyncId ( parent ) :
310312 getDefaultTriggerAsyncId ( ) ;
313+ }
311314
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 ) ;
316320}
317321
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+ }
326328
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 ) ;
328334 }
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+ }
329344
345+ function promiseResolveHook ( promise ) {
346+ trackPromise ( promise ) ;
330347 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 ) ;
353349}
354350
355351let wantPromiseHook = false ;
356352function enableHooks ( ) {
357353 async_hook_fields [ kCheck ] += 1 ;
358354}
359355
360- let promiseHookMode = - 1 ;
361356function updatePromiseHookMode ( ) {
362357 wantPromiseHook = true ;
363358 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+ ) ;
371367 }
372368}
373369
@@ -383,8 +379,8 @@ function disableHooks() {
383379
384380function disablePromiseHookIfNecessary ( ) {
385381 if ( ! wantPromiseHook ) {
386- promiseHookMode = - 1 ;
387382 disablePromiseHook ( ) ;
383+ setPromiseHooks ( undefined , undefined , undefined , undefined ) ;
388384 }
389385}
390386
@@ -458,6 +454,10 @@ function destroyHooksExist() {
458454 return hasHooks ( kDestroy ) ;
459455}
460456
457+ function promiseResolveHooksExist ( ) {
458+ return hasHooks ( kPromiseResolve ) ;
459+ }
460+
461461
462462function emitInitScript ( asyncId , type , triggerAsyncId , resource ) {
463463 // Short circuit all checks for the common case. Which is that no hooks have
0 commit comments