@@ -49,15 +49,18 @@ const init_symbol = Symbol('init');
4949const before_symbol = Symbol('before');
5050const after_symbol = Symbol('after');
5151const 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');
5255
5356// Setup the callbacks that node::AsyncWrap will call when there are hooks to
5457// process. They use the same functions as the JS embedder API. These callbacks
5558// are setup immediately to prevent async_wrap.setupHooks() from being hijacked
5659// and the cost of doing so is negligible.
5760async_wrap.setupHooks({ init,
58- before: emitBeforeN ,
59- after: emitAfterN ,
60- destroy: emitDestroyN });
61+ before: emitBeforeNative ,
62+ after: emitAfterNative ,
63+ destroy: emitDestroyNative });
6164
6265// Used to fatally abort the process if a callback throws.
6366function fatalError(e) {
@@ -325,8 +328,8 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
325328 triggerAsyncId = initTriggerId();
326329 }
327330
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.
330333 if (!Number.isSafeInteger(asyncId) || asyncId < 0)
331334 throw new RangeError('asyncId must be an unsigned integer');
332335 if (typeof type !== 'string' || type.length <= 0)
@@ -342,24 +345,35 @@ function emitInitS(asyncId, type, triggerAsyncId, resource) {
342345 }
343346}
344347
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+ }
353361 }
362+ } catch (e) {
363+ fatalError(e);
354364 }
355- } catch (e) {
356- fatalError(e);
357- }
358- processing_hook = false;
365+ processing_hook = false;
359366
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;
363377}
364378
365379
@@ -379,29 +393,7 @@ function emitBeforeS(asyncId, triggerAsyncId = asyncId) {
379393
380394 if (async_hook_fields[kBefore] === 0)
381395 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);
405397}
406398
407399
@@ -410,7 +402,7 @@ function emitAfterN(asyncId) {
410402// after callbacks.
411403function emitAfterS(asyncId) {
412404 if (async_hook_fields[kAfter] > 0)
413- emitAfterN (asyncId);
405+ emitAfterNative (asyncId);
414406
415407 popAsyncIds(asyncId);
416408}
@@ -425,26 +417,6 @@ function emitDestroyS(asyncId) {
425417}
426418
427419
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-
448420// Emit callbacks for native calls. Since some state can be setup directly from
449421// C++ there's no need to perform all the work here.
450422
0 commit comments