| Index: src/builtins/builtins-async-function.cc
|
| diff --git a/src/builtins/builtins-async-function.cc b/src/builtins/builtins-async-function.cc
|
| deleted file mode 100644
|
| index 309d4815336fbc585817fe6875788c6ea0481483..0000000000000000000000000000000000000000
|
| --- a/src/builtins/builtins-async-function.cc
|
| +++ /dev/null
|
| @@ -1,208 +0,0 @@
|
| -// Copyright 2017 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "src/builtins/builtins-async.h"
|
| -#include "src/builtins/builtins-utils.h"
|
| -#include "src/builtins/builtins.h"
|
| -#include "src/code-stub-assembler.h"
|
| -#include "src/objects-inl.h"
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -typedef compiler::Node Node;
|
| -typedef CodeStubAssembler::ParameterMode ParameterMode;
|
| -typedef compiler::CodeAssemblerState CodeAssemblerState;
|
| -
|
| -class AsyncFunctionBuiltinsAssembler : public AsyncBuiltinsAssembler {
|
| - public:
|
| - explicit AsyncFunctionBuiltinsAssembler(CodeAssemblerState* state)
|
| - : AsyncBuiltinsAssembler(state) {}
|
| -
|
| - protected:
|
| - void AsyncFunctionAwait(Node* const context, Node* const generator,
|
| - Node* const awaited, Node* const outer_promise,
|
| - const bool is_predicted_as_caught);
|
| -
|
| - void AsyncFunctionAwaitResumeClosure(
|
| - Node* const context, Node* const sent_value,
|
| - JSGeneratorObject::ResumeMode resume_mode);
|
| -};
|
| -
|
| -namespace {
|
| -
|
| -// Describe fields of Context associated with AsyncFunctionAwait resume
|
| -// closures.
|
| -// TODO(jgruber): Refactor to reuse code for upcoming async-generators.
|
| -class AwaitContext {
|
| - public:
|
| - enum Fields { kGeneratorSlot = Context::MIN_CONTEXT_SLOTS, kLength };
|
| -};
|
| -
|
| -} // anonymous namespace
|
| -
|
| -void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResumeClosure(
|
| - Node* context, Node* sent_value,
|
| - JSGeneratorObject::ResumeMode resume_mode) {
|
| - DCHECK(resume_mode == JSGeneratorObject::kNext ||
|
| - resume_mode == JSGeneratorObject::kThrow);
|
| -
|
| - Node* const generator =
|
| - LoadContextElement(context, AwaitContext::kGeneratorSlot);
|
| - CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
|
| -
|
| - // Inline version of GeneratorPrototypeNext / GeneratorPrototypeReturn with
|
| - // unnecessary runtime checks removed.
|
| - // TODO(jgruber): Refactor to reuse code from builtins-generator.cc.
|
| -
|
| - // Ensure that the generator is neither closed nor running.
|
| - CSA_SLOW_ASSERT(
|
| - this,
|
| - SmiGreaterThan(
|
| - LoadObjectField(generator, JSGeneratorObject::kContinuationOffset),
|
| - SmiConstant(JSGeneratorObject::kGeneratorClosed)));
|
| -
|
| - // Resume the {receiver} using our trampoline.
|
| - Callable callable = CodeFactory::ResumeGenerator(isolate());
|
| - CallStub(callable, context, sent_value, generator, SmiConstant(resume_mode));
|
| -
|
| - // The resulting Promise is a throwaway, so it doesn't matter what it
|
| - // resolves to. What is important is that we don't end up keeping the
|
| - // whole chain of intermediate Promises alive by returning the return value
|
| - // of ResumeGenerator, as that would create a memory leak.
|
| -}
|
| -
|
| -TF_BUILTIN(AsyncFunctionAwaitRejectClosure, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 1);
|
| - Node* const sentError = Parameter(1);
|
| - Node* const context = Parameter(4);
|
| -
|
| - AsyncFunctionAwaitResumeClosure(context, sentError,
|
| - JSGeneratorObject::kThrow);
|
| - Return(UndefinedConstant());
|
| -}
|
| -
|
| -TF_BUILTIN(AsyncFunctionAwaitResolveClosure, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 1);
|
| - Node* const sentValue = Parameter(1);
|
| - Node* const context = Parameter(4);
|
| -
|
| - AsyncFunctionAwaitResumeClosure(context, sentValue, JSGeneratorObject::kNext);
|
| - Return(UndefinedConstant());
|
| -}
|
| -
|
| -// ES#abstract-ops-async-function-await
|
| -// AsyncFunctionAwait ( value )
|
| -// Shared logic for the core of await. The parser desugars
|
| -// await awaited
|
| -// into
|
| -// yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise)
|
| -// The 'awaited' parameter is the value; the generator stands in
|
| -// for the asyncContext, and .promise is the larger promise under
|
| -// construction by the enclosing async function.
|
| -void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
|
| - Node* const context, Node* const generator, Node* const awaited,
|
| - Node* const outer_promise, const bool is_predicted_as_caught) {
|
| - CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
|
| - CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE));
|
| -
|
| - NodeGenerator1 create_closure_context = [&](Node* native_context) -> Node* {
|
| - Node* const context =
|
| - CreatePromiseContext(native_context, AwaitContext::kLength);
|
| - StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
|
| - generator);
|
| - return context;
|
| - };
|
| -
|
| - // TODO(jgruber): AsyncBuiltinsAssembler::Await currently does not reuse
|
| - // the awaited promise if it is already a promise. Reuse is non-spec compliant
|
| - // but part of our old behavior gives us a couple of percent
|
| - // performance boost.
|
| - // TODO(jgruber): Use a faster specialized version of
|
| - // InternalPerformPromiseThen.
|
| -
|
| - Node* const result = Await(
|
| - context, generator, awaited, outer_promise, create_closure_context,
|
| - Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
|
| - Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, is_predicted_as_caught);
|
| -
|
| - Return(result);
|
| -}
|
| -
|
| -// Called by the parser from the desugaring of 'await' when catch
|
| -// prediction indicates that there is a locally surrounding catch block.
|
| -TF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 3);
|
| - Node* const generator = Parameter(1);
|
| - Node* const awaited = Parameter(2);
|
| - Node* const outer_promise = Parameter(3);
|
| - Node* const context = Parameter(6);
|
| -
|
| - static const bool kIsPredictedAsCaught = true;
|
| -
|
| - AsyncFunctionAwait(context, generator, awaited, outer_promise,
|
| - kIsPredictedAsCaught);
|
| -}
|
| -
|
| -// Called by the parser from the desugaring of 'await' when catch
|
| -// prediction indicates no locally surrounding catch block.
|
| -TF_BUILTIN(AsyncFunctionAwaitUncaught, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 3);
|
| - Node* const generator = Parameter(1);
|
| - Node* const awaited = Parameter(2);
|
| - Node* const outer_promise = Parameter(3);
|
| - Node* const context = Parameter(6);
|
| -
|
| - static const bool kIsPredictedAsCaught = false;
|
| -
|
| - AsyncFunctionAwait(context, generator, awaited, outer_promise,
|
| - kIsPredictedAsCaught);
|
| -}
|
| -
|
| -TF_BUILTIN(AsyncFunctionPromiseCreate, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 0);
|
| - Node* const context = Parameter(3);
|
| -
|
| - Node* const promise = AllocateAndInitJSPromise(context);
|
| -
|
| - Label if_is_debug_active(this, Label::kDeferred);
|
| - GotoIf(IsDebugActive(), &if_is_debug_active);
|
| -
|
| - // Early exit if debug is not active.
|
| - Return(promise);
|
| -
|
| - Bind(&if_is_debug_active);
|
| - {
|
| - // Push the Promise under construction in an async function on
|
| - // the catch prediction stack to handle exceptions thrown before
|
| - // the first await.
|
| - // Assign ID and create a recurring task to save stack for future
|
| - // resumptions from await.
|
| - CallRuntime(Runtime::kDebugAsyncFunctionPromiseCreated, context, promise);
|
| - Return(promise);
|
| - }
|
| -}
|
| -
|
| -TF_BUILTIN(AsyncFunctionPromiseRelease, AsyncFunctionBuiltinsAssembler) {
|
| - CSA_ASSERT_JS_ARGC_EQ(this, 1);
|
| - Node* const promise = Parameter(1);
|
| - Node* const context = Parameter(4);
|
| -
|
| - Label if_is_debug_active(this, Label::kDeferred);
|
| - GotoIf(IsDebugActive(), &if_is_debug_active);
|
| -
|
| - // Early exit if debug is not active.
|
| - Return(UndefinedConstant());
|
| -
|
| - Bind(&if_is_debug_active);
|
| - {
|
| - // Pop the Promise under construction in an async function on
|
| - // from catch prediction stack.
|
| - CallRuntime(Runtime::kDebugPopPromise, context);
|
| - Return(promise);
|
| - }
|
| -}
|
| -
|
| -} // namespace internal
|
| -} // namespace v8
|
|
|