| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f421422 commit 214e568
31 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 37 | # Reset this number to 0 on major V8 upgrades. | |
| 38 | 38 | # Increment by one for each non-official patch applied to deps/v8. | |
| 39 | - 'v8_embedder_string': '-node.76', | ||
| 39 | + 'v8_embedder_string': '-node.77', | ||
| 40 | 40 | ||
| 41 | 41 | ##### V8 defaults for Node.js ##### | |
| 42 | 42 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -190,6 +190,7 @@ Seo Sanghyeon <sanxiyn@gmail.com> | |||
| 190 | 190 | Shawn Anastasio <shawnanastasio@gmail.com> | |
| 191 | 191 | Shawn Presser <shawnpresser@gmail.com> | |
| 192 | 192 | Stefan Penner <stefan.penner@gmail.com> | |
| 193 | + Stephen Belanger <stephen.belanger@datadoghq.com> | ||
| 193 | 194 | Sylvestre Ledru <sledru@mozilla.com> | |
| 194 | 195 | Taketoshi Aono <brn@b6n.ch> | |
| 195 | 196 | Teddy Katz <teddy.katz@gmail.com> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10488,6 +10488,18 @@ class V8_EXPORT Context { | |||
| 10488 | 10488 | */ | |
| 10489 | 10489 | void SetContinuationPreservedEmbedderData(Local<Value> context); | |
| 10490 | 10490 | ||
| 10491 | + /** | ||
| 10492 | + * Set or clear hooks to be invoked for promise lifecycle operations. | ||
| 10493 | + * To clear a hook, set it to an empty v8::Function. Each function will | ||
| 10494 | + * receive the observed promise as the first argument. If a chaining | ||
| 10495 | + * operation is used on a promise, the init will additionally receive | ||
| 10496 | + * the parent promise as the second argument. | ||
| 10497 | + */ | ||
| 10498 | + void SetPromiseHooks(Local<Function> init_hook, | ||
| 10499 | + Local<Function> before_hook, | ||
| 10500 | + Local<Function> after_hook, | ||
| 10501 | + Local<Function> resolve_hook); | ||
| 10502 | + | ||
| 10491 | 10503 | /** | |
| 10492 | 10504 | * Stack-allocated class which sets the execution context for all | |
| 10493 | 10505 | * operations executed within a local scope. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6078,6 +6078,45 @@ void Context::SetContinuationPreservedEmbedderData(Local<Value> data) { | |||
| 6078 | 6078 | *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data))); | |
| 6079 | 6079 | } | |
| 6080 | 6080 | ||
| 6081 | + void v8::Context::SetPromiseHooks(Local<Function> init_hook, | ||
| 6082 | + Local<Function> before_hook, | ||
| 6083 | + Local<Function> after_hook, | ||
| 6084 | + Local<Function> resolve_hook) { | ||
| 6085 | + i::Handle<i::Context> context = Utils::OpenHandle(this); | ||
| 6086 | + i::Isolate* isolate = context->GetIsolate(); | ||
| 6087 | + | ||
| 6088 | + i::Handle<i::Object> init = isolate->factory()->undefined_value(); | ||
| 6089 | + i::Handle<i::Object> before = isolate->factory()->undefined_value(); | ||
| 6090 | + i::Handle<i::Object> after = isolate->factory()->undefined_value(); | ||
| 6091 | + i::Handle<i::Object> resolve = isolate->factory()->undefined_value(); | ||
| 6092 | + | ||
| 6093 | + bool has_hook = false; | ||
| 6094 | + | ||
| 6095 | + if (!init_hook.IsEmpty()) { | ||
| 6096 | + init = Utils::OpenHandle(*init_hook); | ||
| 6097 | + has_hook = true; | ||
| 6098 | + } | ||
| 6099 | + if (!before_hook.IsEmpty()) { | ||
| 6100 | + before = Utils::OpenHandle(*before_hook); | ||
| 6101 | + has_hook = true; | ||
| 6102 | + } | ||
| 6103 | + if (!after_hook.IsEmpty()) { | ||
| 6104 | + after = Utils::OpenHandle(*after_hook); | ||
| 6105 | + has_hook = true; | ||
| 6106 | + } | ||
| 6107 | + if (!resolve_hook.IsEmpty()) { | ||
| 6108 | + resolve = Utils::OpenHandle(*resolve_hook); | ||
| 6109 | + has_hook = true; | ||
| 6110 | + } | ||
| 6111 | + | ||
| 6112 | + isolate->SetHasContextPromiseHooks(has_hook); | ||
| 6113 | + | ||
| 6114 | + context->native_context().set_promise_hook_init_function(*init); | ||
| 6115 | + context->native_context().set_promise_hook_before_function(*before); | ||
| 6116 | + context->native_context().set_promise_hook_after_function(*after); | ||
| 6117 | + context->native_context().set_promise_hook_resolve_function(*resolve); | ||
| 6118 | + } | ||
| 6119 | + | ||
| 6081 | 6120 | namespace { | |
| 6082 | 6121 | i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate, | |
| 6083 | 6122 | i::FixedArray list, size_t index) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -157,12 +157,14 @@ TF_BUILTIN(AsyncFunctionEnter, AsyncFunctionBuiltinsAssembler) { | |||
| 157 | 157 | StoreObjectFieldNoWriteBarrier( | |
| 158 | 158 | async_function_object, JSAsyncFunctionObject::kPromiseOffset, promise); | |
| 159 | 159 | ||
| 160 | + RunContextPromiseHookInit(context, promise, UndefinedConstant()); | ||
| 161 | + | ||
| 160 | 162 | // Fire promise hooks if enabled and push the Promise under construction | |
| 161 | 163 | // in an async function on the catch prediction stack to handle exceptions | |
| 162 | 164 | // thrown before the first await. | |
| 163 | 165 | Label if_instrumentation(this, Label::kDeferred), | |
| 164 | 166 | if_instrumentation_done(this); | |
| 165 | - Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), | ||
| 167 | + Branch(IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), | ||
| 166 | 168 | &if_instrumentation, &if_instrumentation_done); | |
| 167 | 169 | BIND(&if_instrumentation); | |
| 168 | 170 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,18 +99,11 @@ TNode<Object> AsyncBuiltinsAssembler::AwaitOld( | |||
| 99 | 99 | ||
| 100 | 100 | TVARIABLE(HeapObject, var_throwaway, UndefinedConstant()); | |
| 101 | 101 | ||
| 102 | - // Deal with PromiseHooks and debug support in the runtime. This | ||
| 103 | - // also allocates the throwaway promise, which is only needed in | ||
| 104 | - // case of PromiseHooks or debugging. | ||
| 105 | - Label if_debugging(this, Label::kDeferred), do_resolve_promise(this); | ||
| 106 | - Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), | ||
| 107 | - &if_debugging, &do_resolve_promise); | ||
| 108 | - BIND(&if_debugging); | ||
| 109 | - var_throwaway = | ||
| 110 | - CAST(CallRuntime(Runtime::kAwaitPromisesInitOld, context, value, promise, | ||
| 111 | - outer_promise, on_reject, is_predicted_as_caught)); | ||
| 112 | - Goto(&do_resolve_promise); | ||
| 113 | - BIND(&do_resolve_promise); | ||
| 102 | + RunContextPromiseHookInit(context, promise, outer_promise); | ||
| 103 | + | ||
| 104 | + InitAwaitPromise(Runtime::kAwaitPromisesInitOld, context, value, promise, | ||
| 105 | + outer_promise, on_reject, is_predicted_as_caught, | ||
| 106 | + &var_throwaway); | ||
| 114 | 107 | ||
| 115 | 108 | // Perform ! Call(promiseCapability.[[Resolve]], undefined, « promise »). | |
| 116 | 109 | CallBuiltin(Builtins::kResolvePromise, context, promise, value); | |
@@ -170,21 +163,46 @@ TNode<Object> AsyncBuiltinsAssembler::AwaitOptimized( | |||
| 170 | 163 | ||
| 171 | 164 | TVARIABLE(HeapObject, var_throwaway, UndefinedConstant()); | |
| 172 | 165 | ||
| 166 | + InitAwaitPromise(Runtime::kAwaitPromisesInit, context, promise, promise, | ||
| 167 | + outer_promise, on_reject, is_predicted_as_caught, | ||
| 168 | + &var_throwaway); | ||
| 169 | + | ||
| 170 | + return CallBuiltin(Builtins::kPerformPromiseThen, native_context, promise, | ||
| 171 | + on_resolve, on_reject, var_throwaway.value()); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + void AsyncBuiltinsAssembler::InitAwaitPromise( | ||
| 175 | + Runtime::FunctionId id, TNode<Context> context, TNode<Object> value, | ||
| 176 | + TNode<Object> promise, TNode<Object> outer_promise, | ||
| 177 | + TNode<HeapObject> on_reject, TNode<Oddball> is_predicted_as_caught, | ||
| 178 | + TVariable<HeapObject>* var_throwaway) { | ||
| 173 | 179 | // Deal with PromiseHooks and debug support in the runtime. This | |
| 174 | 180 | // also allocates the throwaway promise, which is only needed in | |
| 175 | 181 | // case of PromiseHooks or debugging. | |
| 176 | - Label if_debugging(this, Label::kDeferred), do_perform_promise_then(this); | ||
| 177 | - Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), | ||
| 178 | - &if_debugging, &do_perform_promise_then); | ||
| 182 | + Label if_debugging(this, Label::kDeferred), | ||
| 183 | + if_promise_hook(this, Label::kDeferred), | ||
| 184 | + not_debugging(this), | ||
| 185 | + do_nothing(this); | ||
| 186 | + TNode<Uint32T> promiseHookFlags = PromiseHookFlags(); | ||
| 187 | + Branch(IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate( | ||
| 188 | + promiseHookFlags), &if_debugging, ¬_debugging); | ||
| 179 | 189 | BIND(&if_debugging); | |
| 180 | - var_throwaway = | ||
| 181 | - CAST(CallRuntime(Runtime::kAwaitPromisesInit, context, promise, promise, | ||
| 190 | + *var_throwaway = | ||
| 191 | + CAST(CallRuntime(id, context, value, promise, | ||
| 182 | 192 | outer_promise, on_reject, is_predicted_as_caught)); | |
| 183 | - Goto(&do_perform_promise_then); | ||
| 184 | - BIND(&do_perform_promise_then); | ||
| 185 | - | ||
| 186 | - return CallBuiltin(Builtins::kPerformPromiseThen, native_context, promise, | ||
| 187 | - on_resolve, on_reject, var_throwaway.value()); | ||
| 193 | + Goto(&do_nothing); | ||
| 194 | + BIND(¬_debugging); | ||
| 195 | + | ||
| 196 | + // This call to NewJSPromise is to keep behaviour parity with what happens | ||
| 197 | + // in Runtime::kAwaitPromisesInit above if native hooks are set. It will | ||
| 198 | + // create a throwaway promise that will trigger an init event and will get | ||
| 199 | + // passed into Builtins::kPerformPromiseThen below. | ||
| 200 | + Branch(IsContextPromiseHookEnabled(promiseHookFlags), &if_promise_hook, | ||
| 201 | + &do_nothing); | ||
| 202 | + BIND(&if_promise_hook); | ||
| 203 | + *var_throwaway = NewJSPromise(context, promise); | ||
| 204 | + Goto(&do_nothing); | ||
| 205 | + BIND(&do_nothing); | ||
| 188 | 206 | } | |
| 189 | 207 | ||
| 190 | 208 | TNode<Object> AsyncBuiltinsAssembler::Await( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,6 +62,12 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler { | |||
| 62 | 62 | TNode<SharedFunctionInfo> on_resolve_sfi, | |
| 63 | 63 | TNode<SharedFunctionInfo> on_reject_sfi, | |
| 64 | 64 | TNode<Oddball> is_predicted_as_caught); | |
| 65 | + | ||
| 66 | + void InitAwaitPromise( | ||
| 67 | + Runtime::FunctionId id, TNode<Context> context, TNode<Object> value, | ||
| 68 | + TNode<Object> promise, TNode<Object> outer_promise, | ||
| 69 | + TNode<HeapObject> on_reject, TNode<Oddball> is_predicted_as_caught, | ||
| 70 | + TVariable<HeapObject>* var_throwaway); | ||
| 65 | 71 | }; | |
| 66 | 72 | ||
| 67 | 73 | } // namespace internal | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -520,7 +520,7 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) { | |||
| 520 | 520 | // the "promiseResolve" hook would not be fired otherwise. | |
| 521 | 521 | Label if_fast(this), if_slow(this, Label::kDeferred), return_promise(this); | |
| 522 | 522 | GotoIfForceSlowPath(&if_slow); | |
| 523 | - GotoIf(IsPromiseHookEnabled(), &if_slow); | ||
| 523 | + GotoIf(IsIsolatePromiseHookEnabledOrHasAsyncEventDelegate(), &if_slow); | ||
| 524 | 524 | Branch(IsPromiseThenProtectorCellInvalid(), &if_slow, &if_fast); | |
| 525 | 525 | ||
| 526 | 526 | BIND(&if_fast); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,8 +46,11 @@ class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler { | |||
| 46 | 46 | void EnterMicrotaskContext(TNode<Context> native_context); | |
| 47 | 47 | void RewindEnteredContext(TNode<IntPtrT> saved_entered_context_count); | |
| 48 | 48 | ||
| 49 | + void RunAllPromiseHooks(PromiseHookType type, TNode<Context> context, | ||
| 50 | + TNode<HeapObject> promise_or_capability); | ||
| 49 | 51 | void RunPromiseHook(Runtime::FunctionId id, TNode<Context> context, | |
| 50 | - TNode<HeapObject> promise_or_capability); | ||
| 52 | + TNode<HeapObject> promise_or_capability, | ||
| 53 | + TNode<Uint32T> promiseHookFlags); | ||
| 51 | 54 | }; | |
| 52 | 55 | ||
| 53 | 56 | TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueue( | |
@@ -198,7 +201,7 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 198 | 201 | const TNode<Object> thenable = LoadObjectField( | |
| 199 | 202 | microtask, PromiseResolveThenableJobTask::kThenableOffset); | |
| 200 | 203 | ||
| 201 | - RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context, | ||
| 204 | + RunAllPromiseHooks(PromiseHookType::kBefore, microtask_context, | ||
| 202 | 205 | CAST(promise_to_resolve)); | |
| 203 | 206 | ||
| 204 | 207 | { | |
@@ -207,7 +210,7 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 207 | 210 | promise_to_resolve, thenable, then); | |
| 208 | 211 | } | |
| 209 | 212 | ||
| 210 | - RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context, | ||
| 213 | + RunAllPromiseHooks(PromiseHookType::kAfter, microtask_context, | ||
| 211 | 214 | CAST(promise_to_resolve)); | |
| 212 | 215 | ||
| 213 | 216 | RewindEnteredContext(saved_entered_context_count); | |
@@ -242,8 +245,8 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 242 | 245 | BIND(&preserved_data_done); | |
| 243 | 246 | ||
| 244 | 247 | // Run the promise before/debug hook if enabled. | |
| 245 | - RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context, | ||
| 246 | - promise_or_capability); | ||
| 248 | + RunAllPromiseHooks(PromiseHookType::kBefore, microtask_context, | ||
| 249 | + promise_or_capability); | ||
| 247 | 250 | ||
| 248 | 251 | { | |
| 249 | 252 | ScopedExceptionHandler handler(this, &if_exception, &var_exception); | |
@@ -252,8 +255,8 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 252 | 255 | } | |
| 253 | 256 | ||
| 254 | 257 | // Run the promise after/debug hook if enabled. | |
| 255 | - RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context, | ||
| 256 | - promise_or_capability); | ||
| 258 | + RunAllPromiseHooks(PromiseHookType::kAfter, microtask_context, | ||
| 259 | + promise_or_capability); | ||
| 257 | 260 | ||
| 258 | 261 | Label preserved_data_reset_done(this); | |
| 259 | 262 | GotoIf(IsUndefined(preserved_embedder_data), &preserved_data_reset_done); | |
@@ -295,8 +298,8 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 295 | 298 | BIND(&preserved_data_done); | |
| 296 | 299 | ||
| 297 | 300 | // Run the promise before/debug hook if enabled. | |
| 298 | - RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context, | ||
| 299 | - promise_or_capability); | ||
| 301 | + RunAllPromiseHooks(PromiseHookType::kBefore, microtask_context, | ||
| 302 | + promise_or_capability); | ||
| 300 | 303 | ||
| 301 | 304 | { | |
| 302 | 305 | ScopedExceptionHandler handler(this, &if_exception, &var_exception); | |
@@ -305,8 +308,8 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( | |||
| 305 | 308 | } | |
| 306 | 309 | ||
| 307 | 310 | // Run the promise after/debug hook if enabled. | |
| 308 | - RunPromiseHook(Runtime::kPromiseHookAfter, microtask_context, | ||
| 309 | - promise_or_capability); | ||
| 311 | + RunAllPromiseHooks(PromiseHookType::kAfter, microtask_context, | ||
| 312 | + promise_or_capability); | ||
| 310 | 313 | ||
| 311 | 314 | Label preserved_data_reset_done(this); | |
| 312 | 315 | GotoIf(IsUndefined(preserved_embedder_data), &preserved_data_reset_done); | |
@@ -464,12 +467,43 @@ void MicrotaskQueueBuiltinsAssembler::RewindEnteredContext( | |||
| 464 | 467 | saved_entered_context_count); | |
| 465 | 468 | } | |
| 466 | 469 | ||
| 470 | + void MicrotaskQueueBuiltinsAssembler::RunAllPromiseHooks( | ||
| 471 | + PromiseHookType type, TNode<Context> context, | ||
| 472 | + TNode<HeapObject> promise_or_capability) { | ||
| 473 | + Label hook(this, Label::kDeferred), done_hook(this); | ||
| 474 | + TNode<Uint32T> promiseHookFlags = PromiseHookFlags(); | ||
| 475 | + Branch(IsAnyPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate( | ||
| 476 | + promiseHookFlags), &hook, &done_hook); | ||
| 477 | + BIND(&hook); | ||
| 478 | + { | ||
| 479 | + switch (type) { | ||
| 480 | + case PromiseHookType::kBefore: | ||
| 481 | + RunContextPromiseHookBefore(context, promise_or_capability, | ||
| 482 | + promiseHookFlags); | ||
| 483 | + RunPromiseHook(Runtime::kPromiseHookBefore, context, | ||
| 484 | + promise_or_capability, promiseHookFlags); | ||
| 485 | + break; | ||
| 486 | + case PromiseHookType::kAfter: | ||
| 487 | + RunContextPromiseHookAfter(context, promise_or_capability, | ||
| 488 | + promiseHookFlags); | ||
| 489 | + RunPromiseHook(Runtime::kPromiseHookAfter, context, | ||
| 490 | + promise_or_capability, promiseHookFlags); | ||
| 491 | + break; | ||
| 492 | + default: | ||
| 493 | + UNREACHABLE(); | ||
| 494 | + } | ||
| 495 | + Goto(&done_hook); | ||
| 496 | + } | ||
| 497 | + BIND(&done_hook); | ||
| 498 | + } | ||
| 499 | + | ||
| 467 | 500 | void MicrotaskQueueBuiltinsAssembler::RunPromiseHook( | |
| 468 | 501 | Runtime::FunctionId id, TNode<Context> context, | |
| 469 | - TNode<HeapObject> promise_or_capability) { | ||
| 502 | + TNode<HeapObject> promise_or_capability, | ||
| 503 | + TNode<Uint32T> promiseHookFlags) { | ||
| 470 | 504 | Label hook(this, Label::kDeferred), done_hook(this); | |
| 471 | - Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), &hook, | ||
| 472 | - &done_hook); | ||
| 505 | + Branch(IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate( | ||
| 506 | + promiseHookFlags), &hook, &done_hook); | ||
| 473 | 507 | BIND(&hook); | |
| 474 | 508 | { | |
| 475 | 509 | // Get to the underlying JSPromise instance. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -186,6 +186,8 @@ FulfillPromise(implicit context: Context)( | |||
| 186 | 186 | // Assert: The value of promise.[[PromiseState]] is "pending". | |
| 187 | 187 | assert(promise.Status() == PromiseState::kPending); | |
| 188 | 188 | ||
| 189 | + RunContextPromiseHookResolve(promise); | ||
| 190 | + | ||
| 189 | 191 | // 2. Let reactions be promise.[[PromiseFulfillReactions]]. | |
| 190 | 192 | const reactions = | |
| 191 | 193 | UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result); | |
@@ -204,17 +206,24 @@ FulfillPromise(implicit context: Context)( | |||
| 204 | 206 | } | |
| 205 | 207 | ||
| 206 | 208 | extern macro PromiseBuiltinsAssembler:: | |
| 207 | - IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(): bool; | ||
| 209 | + IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(): bool; | ||
| 210 | + | ||
| 211 | + extern macro PromiseBuiltinsAssembler:: | ||
| 212 | + IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(uint32): | ||
| 213 | + bool; | ||
| 208 | 214 | ||
| 209 | 215 | // https://tc39.es/ecma262/#sec-rejectpromise | |
| 210 | 216 | transitioning builtin | |
| 211 | 217 | RejectPromise(implicit context: Context)( | |
| 212 | 218 | promise: JSPromise, reason: JSAny, debugEvent: Boolean): JSAny { | |
| 219 | + const promiseHookFlags = PromiseHookFlags(); | ||
| 220 | + | ||
| 213 | 221 | // If promise hook is enabled or the debugger is active, let | |
| 214 | 222 | // the runtime handle this operation, which greatly reduces | |
| 215 | 223 | // the complexity here and also avoids a couple of back and | |
| 216 | 224 | // forth between JavaScript and C++ land. | |
| 217 | - if (IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() || | ||
| 225 | + if (IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate( | ||
| 226 | + promiseHookFlags) || | ||
| 218 | 227 | !promise.HasHandler()) { | |
| 219 | 228 | // 7. If promise.[[PromiseIsHandled]] is false, perform | |
| 220 | 229 | // HostPromiseRejectionTracker(promise, "reject"). | |
@@ -223,6 +232,8 @@ RejectPromise(implicit context: Context)( | |||
| 223 | 232 | return runtime::RejectPromise(promise, reason, debugEvent); | |
| 224 | 233 | } | |
| 225 | 234 | ||
| 235 | + RunContextPromiseHookResolve(promise, promiseHookFlags); | ||
| 236 | + | ||
| 226 | 237 | // 2. Let reactions be promise.[[PromiseRejectReactions]]. | |
| 227 | 238 | const reactions = | |
| 228 | 239 | UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments