| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 524b230 commit 0d79c53
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,13 +1,16 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | + ArrayPrototypeUnshift, | ||
| 4 | 5 | Error, | |
| 5 | 6 | FunctionPrototypeBind, | |
| 6 | 7 | ObjectDefineProperty, | |
| 8 | + ReflectApply, | ||
| 7 | 9 | Symbol, | |
| 8 | 10 | } = primordials; | |
| 9 | 11 | ||
| 10 | 12 | const async_wrap = internalBinding('async_wrap'); | |
| 13 | + const { setCallbackTrampoline } = async_wrap; | ||
| 11 | 14 | /* async_hook_fields is a Uint32Array wrapping the uint32_t array of | |
| 12 | 15 | * Environment::AsyncHooks::fields_[]. Each index tracks the number of active | |
| 13 | 16 | * hooks for each type. | |
@@ -100,6 +103,26 @@ const emitDestroyNative = emitHookFactory(destroy_symbol, 'emitDestroyNative'); | |||
| 100 | 103 | const emitPromiseResolveNative = | |
| 101 | 104 | emitHookFactory(promise_resolve_symbol, 'emitPromiseResolveNative'); | |
| 102 | 105 | ||
| 106 | + function callbackTrampoline(asyncId, cb, domain_cb, ...args) { | ||
| 107 | + if (hasHooks(kBefore)) | ||
| 108 | + emitBeforeNative(asyncId); | ||
| 109 | + | ||
| 110 | + let result; | ||
| 111 | + if (typeof domain_cb === 'function') { | ||
| 112 | + ArrayPrototypeUnshift(args, cb); | ||
| 113 | + result = ReflectApply(domain_cb, this, args); | ||
| 114 | + } else { | ||
| 115 | + result = ReflectApply(cb, this, args); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + if (hasHooks(kAfter)) | ||
| 119 | + emitAfterNative(asyncId); | ||
| 120 | + | ||
| 121 | + return result; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + setCallbackTrampoline(callbackTrampoline); | ||
| 125 | + | ||
| 103 | 126 | const topLevelResource = {}; | |
| 104 | 127 | ||
| 105 | 128 | function executionAsyncResource() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -158,20 +158,46 @@ MaybeLocal<Value> InternalMakeCallback(Environment* env, | |||
| 158 | 158 | CHECK(!argv[i].IsEmpty()); | |
| 159 | 159 | #endif | |
| 160 | 160 | ||
| 161 | - InternalCallbackScope scope(env, resource, asyncContext); | ||
| 161 | + Local<Function> hook_cb = env->async_hooks_callback_trampoline(); | ||
| 162 | + int flags = InternalCallbackScope::kNoFlags; | ||
| 163 | + int hook_count = 0; | ||
| 164 | + if (!hook_cb.IsEmpty()) { | ||
| 165 | + flags = InternalCallbackScope::kSkipAsyncHooks; | ||
| 166 | + AsyncHooks* async_hooks = env->async_hooks(); | ||
| 167 | + hook_count = async_hooks->fields()[AsyncHooks::kBefore] + | ||
| 168 | + async_hooks->fields()[AsyncHooks::kAfter]; | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + InternalCallbackScope scope(env, resource, asyncContext, flags); | ||
| 162 | 172 | if (scope.Failed()) { | |
| 163 | 173 | return MaybeLocal<Value>(); | |
| 164 | 174 | } | |
| 165 | 175 | ||
| 166 | 176 | Local<Function> domain_cb = env->domain_callback(); | |
| 167 | 177 | MaybeLocal<Value> ret; | |
| 168 | - if (asyncContext.async_id != 0 || domain_cb.IsEmpty()) { | ||
| 169 | - ret = callback->Call(env->context(), recv, argc, argv); | ||
| 170 | - } else { | ||
| 171 | - std::vector<Local<Value>> args(1 + argc); | ||
| 178 | + | ||
| 179 | + if (asyncContext.async_id != 0 && hook_count != 0) { | ||
| 180 | + MaybeStackBuffer<Local<Value>, 16> args(3 + argc); | ||
| 181 | + args[0] = v8::Number::New(env->isolate(), asyncContext.async_id); | ||
| 182 | + args[1] = callback; | ||
| 183 | + if (domain_cb.IsEmpty()) { | ||
| 184 | + args[2] = Undefined(env->isolate()); | ||
| 185 | + } else { | ||
| 186 | + args[2] = domain_cb; | ||
| 187 | + } | ||
| 188 | + for (int i = 0; i < argc; i++) { | ||
| 189 | + args[i + 3] = argv[i]; | ||
| 190 | + } | ||
| 191 | + ret = hook_cb->Call(env->context(), recv, args.length(), &args[0]); | ||
| 192 | + } else if (asyncContext.async_id == 0 && !domain_cb.IsEmpty()) { | ||
| 193 | + MaybeStackBuffer<Local<Value>, 16> args(1 + argc); | ||
| 172 | 194 | args[0] = callback; | |
| 173 | - std::copy(&argv[0], &argv[argc], args.begin() + 1); | ||
| 174 | - ret = domain_cb->Call(env->context(), recv, args.size(), &args[0]); | ||
| 195 | + for (int i = 0; i < argc; i++) { | ||
| 196 | + args[i + 1] = argv[i]; | ||
| 197 | + } | ||
| 198 | + ret = domain_cb->Call(env->context(), recv, args.length(), &args[0]); | ||
| 199 | + } else { | ||
| 200 | + ret = callback->Call(env->context(), recv, argc, argv); | ||
| 175 | 201 | } | |
| 176 | 202 | ||
| 177 | 203 | if (ret.IsEmpty()) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -469,6 +469,14 @@ void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo<Value>& args) { | |||
| 469 | 469 | args[0].As<Number>()->Value()); | |
| 470 | 470 | } | |
| 471 | 471 | ||
| 472 | + void AsyncWrap::SetCallbackTrampoline(const FunctionCallbackInfo<Value>& args) { | ||
| 473 | + Environment* env = Environment::GetCurrent(args); | ||
| 474 | + | ||
| 475 | + CHECK(args[0]->IsFunction()); | ||
| 476 | + | ||
| 477 | + env->set_async_hooks_callback_trampoline(args[0].As<Function>()); | ||
| 478 | + } | ||
| 479 | + | ||
| 472 | 480 | Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(Environment* env) { | |
| 473 | 481 | Local<FunctionTemplate> tmpl = env->async_wrap_ctor_template(); | |
| 474 | 482 | if (tmpl.IsEmpty()) { | |
@@ -491,6 +499,7 @@ void AsyncWrap::Initialize(Local<Object> target, | |||
| 491 | 499 | HandleScope scope(isolate); | |
| 492 | 500 | ||
| 493 | 501 | env->SetMethod(target, "setupHooks", SetupHooks); | |
| 502 | + env->SetMethod(target, "setCallbackTrampoline", SetCallbackTrampoline); | ||
| 494 | 503 | env->SetMethod(target, "pushAsyncContext", PushAsyncContext); | |
| 495 | 504 | env->SetMethod(target, "popAsyncContext", PopAsyncContext); | |
| 496 | 505 | env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -140,6 +140,8 @@ class AsyncWrap : public BaseObject { | |||
| 140 | 140 | static void GetProviderType(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 141 | 141 | static void QueueDestroyAsyncId( | |
| 142 | 142 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 143 | + static void SetCallbackTrampoline( | ||
| 144 | + const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 143 | 145 | ||
| 144 | 146 | static void EmitAsyncInit(Environment* env, | |
| 145 | 147 | v8::Local<v8::Object> object, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -434,6 +434,7 @@ constexpr size_t kFsStatsBufferLength = | |||
| 434 | 434 | V(as_callback_data, v8::Object) \ | |
| 435 | 435 | V(async_hooks_after_function, v8::Function) \ | |
| 436 | 436 | V(async_hooks_before_function, v8::Function) \ | |
| 437 | + V(async_hooks_callback_trampoline, v8::Function) \ | ||
| 437 | 438 | V(async_hooks_binding, v8::Object) \ | |
| 438 | 439 | V(async_hooks_destroy_function, v8::Function) \ | |
| 439 | 440 | V(async_hooks_init_function, v8::Function) \ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments