162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Copyright 2017 the V8 project authors. All rights reserved.
262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// found in the LICENSE file.
462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-async.h"
662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-utils.h"
762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-stub-assembler.h"
962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace v8 {
1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace internal {
1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypedef compiler::Node Node;
1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypedef CodeStubAssembler::ParameterMode ParameterMode;
1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypedef compiler::CodeAssemblerState CodeAssemblerState;
1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass AsyncFunctionBuiltinsAssembler : public AsyncBuiltinsAssembler {
1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  explicit AsyncFunctionBuiltinsAssembler(CodeAssemblerState* state)
2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : AsyncBuiltinsAssembler(state) {}
2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protected:
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void AsyncFunctionAwait(Node* const context, Node* const generator,
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          Node* const awaited, Node* const outer_promise,
2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          const bool is_predicted_as_caught);
2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void AsyncFunctionAwaitResumeClosure(
2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* const context, Node* const sent_value,
3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JSGeneratorObject::ResumeMode resume_mode);
3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace {
3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Describe fields of Context associated with AsyncFunctionAwait resume
3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// closures.
3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// TODO(jgruber): Refactor to reuse code for upcoming async-generators.
3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass AwaitContext {
3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  enum Fields { kGeneratorSlot = Context::MIN_CONTEXT_SLOTS, kLength };
4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // anonymous namespace
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResumeClosure(
4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* context, Node* sent_value,
4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    JSGeneratorObject::ResumeMode resume_mode) {
4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(resume_mode == JSGeneratorObject::kNext ||
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         resume_mode == JSGeneratorObject::kThrow);
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const generator =
5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadContextElement(context, AwaitContext::kGeneratorSlot);
5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
5462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Inline version of GeneratorPrototypeNext / GeneratorPrototypeReturn with
5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // unnecessary runtime checks removed.
5762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(jgruber): Refactor to reuse code from builtins-generator.cc.
5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Ensure that the generator is neither closed nor running.
6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_SLOW_ASSERT(
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      this,
6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      SmiGreaterThan(
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          LoadObjectField(generator, JSGeneratorObject::kContinuationOffset),
6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          SmiConstant(JSGeneratorObject::kGeneratorClosed)));
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Resume the {receiver} using our trampoline.
6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Callable callable = CodeFactory::ResumeGenerator(isolate());
6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CallStub(callable, context, sent_value, generator, SmiConstant(resume_mode));
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The resulting Promise is a throwaway, so it doesn't matter what it
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // resolves to. What is important is that we don't end up keeping the
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // whole chain of intermediate Promises alive by returning the return value
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // of ResumeGenerator, as that would create a memory leak.
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionAwaitRejectClosure, AsyncFunctionBuiltinsAssembler) {
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 1);
7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const sentError = Parameter(1);
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(4);
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AsyncFunctionAwaitResumeClosure(context, sentError,
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  JSGeneratorObject::kThrow);
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(UndefinedConstant());
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionAwaitResolveClosure, AsyncFunctionBuiltinsAssembler) {
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 1);
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const sentValue = Parameter(1);
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(4);
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AsyncFunctionAwaitResumeClosure(context, sentValue, JSGeneratorObject::kNext);
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(UndefinedConstant());
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// ES#abstract-ops-async-function-await
9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// AsyncFunctionAwait ( value )
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Shared logic for the core of await. The parser desugars
9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch//   await awaited
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// into
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch//   yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise)
10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// The 'awaited' parameter is the value; the generator stands in
10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// for the asyncContext, and .promise is the larger promise under
10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// construction by the enclosing async function.
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const context, Node* const generator, Node* const awaited,
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const outer_promise, const bool is_predicted_as_caught) {
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE));
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  NodeGenerator1 create_closure_context = [&](Node* native_context) -> Node* {
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const context =
11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CreatePromiseContext(native_context, AwaitContext::kLength);
11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      generator);
11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return context;
11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(jgruber): AsyncBuiltinsAssembler::Await currently does not reuse
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the awaited promise if it is already a promise. Reuse is non-spec compliant
12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // but part of our old behavior gives us a couple of percent
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // performance boost.
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(jgruber): Use a faster specialized version of
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // InternalPerformPromiseThen.
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const result = Await(
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      context, generator, awaited, outer_promise, create_closure_context,
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, is_predicted_as_caught);
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(result);
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Called by the parser from the desugaring of 'await' when catch
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// prediction indicates that there is a locally surrounding catch block.
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 3);
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const generator = Parameter(1);
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const awaited = Parameter(2);
13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const outer_promise = Parameter(3);
14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(6);
14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const bool kIsPredictedAsCaught = true;
14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AsyncFunctionAwait(context, generator, awaited, outer_promise,
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     kIsPredictedAsCaught);
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Called by the parser from the desugaring of 'await' when catch
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// prediction indicates no locally surrounding catch block.
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionAwaitUncaught, AsyncFunctionBuiltinsAssembler) {
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 3);
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const generator = Parameter(1);
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const awaited = Parameter(2);
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const outer_promise = Parameter(3);
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(6);
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const bool kIsPredictedAsCaught = false;
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AsyncFunctionAwait(context, generator, awaited, outer_promise,
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     kIsPredictedAsCaught);
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionPromiseCreate, AsyncFunctionBuiltinsAssembler) {
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 0);
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(3);
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const promise = AllocateAndInitJSPromise(context);
16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label if_is_debug_active(this, Label::kDeferred);
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsDebugActive(), &if_is_debug_active);
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Early exit if debug is not active.
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(promise);
17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_is_debug_active);
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Push the Promise under construction in an async function on
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the catch prediction stack to handle exceptions thrown before
17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the first await.
18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Assign ID and create a recurring task to save stack for future
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // resumptions from await.
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CallRuntime(Runtime::kDebugAsyncFunctionPromiseCreated, context, promise);
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Return(promise);
18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(AsyncFunctionPromiseRelease, AsyncFunctionBuiltinsAssembler) {
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT_JS_ARGC_EQ(this, 1);
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const promise = Parameter(1);
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const context = Parameter(4);
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label if_is_debug_active(this, Label::kDeferred);
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IsDebugActive(), &if_is_debug_active);
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Early exit if debug is not active.
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(UndefinedConstant());
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&if_is_debug_active);
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Pop the Promise under construction in an async function on
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // from catch prediction stack.
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CallRuntime(Runtime::kDebugPopPromise, context);
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Return(promise);
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace internal
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace v8
209