Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: src/builtins/builtins-async-function.cc

Issue 2643023002: [async-await] Move remaining async-await code to TF (Closed)
Patch Set: Typo Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-promise.h" 5 #include "src/builtins/builtins-async.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 #include "src/builtins/builtins.h" 7 #include "src/builtins/builtins.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 typedef compiler::Node Node; 13 typedef compiler::Node Node;
14 typedef CodeStubAssembler::ParameterMode ParameterMode; 14 typedef CodeStubAssembler::ParameterMode ParameterMode;
15 typedef compiler::CodeAssemblerState CodeAssemblerState; 15 typedef compiler::CodeAssemblerState CodeAssemblerState;
16 16
17 class AsyncFunctionBuiltinsAssembler : public PromiseBuiltinsAssembler { 17 class AsyncFunctionBuiltinsAssembler : public AsyncBuiltinsAssembler {
18 public: 18 public:
19 explicit AsyncFunctionBuiltinsAssembler(CodeAssemblerState* state) 19 explicit AsyncFunctionBuiltinsAssembler(CodeAssemblerState* state)
20 : PromiseBuiltinsAssembler(state) {} 20 : AsyncBuiltinsAssembler(state) {}
21
22 protected:
23 void AsyncFunctionAwait(Node* const context, Node* const generator,
24 Node* const awaited, Node* const outer_promise,
25 const bool is_predicted_as_caught);
26
27 void AsyncFunctionAwaitResumeClosure(
28 Node* const context, Node* const sent_value,
29 JSGeneratorObject::ResumeMode resume_mode);
21 }; 30 };
22 31
32 namespace {
33
34 // Describe fields of Context associated with AsyncFunctionAwait resume
35 // closures.
36 // TODO(jgruber): Refactor to reuse code for upcoming async-generators.
37 class AwaitContext {
38 public:
39 enum Fields { kGeneratorSlot = Context::MIN_CONTEXT_SLOTS, kLength };
40 };
41
42 } // anonymous namespace
43
44 void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwaitResumeClosure(
45 Node* context, Node* sent_value,
46 JSGeneratorObject::ResumeMode resume_mode) {
47 DCHECK(resume_mode == JSGeneratorObject::kNext ||
48 resume_mode == JSGeneratorObject::kThrow);
49
50 Node* const generator =
51 LoadContextElement(context, AwaitContext::kGeneratorSlot);
52 CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
53
54 // Inline version of GeneratorPrototypeNext / GeneratorPrototypeReturn with
55 // unnecessary runtime checks removed.
56 // TODO(jgruber): Refactor to reuse code from builtins-generator.cc.
57
58 // Ensure that the generator is neither closed nor running.
59 CSA_SLOW_ASSERT(
60 this,
61 SmiGreaterThan(
62 LoadObjectField(generator, JSGeneratorObject::kContinuationOffset),
63 SmiConstant(JSGeneratorObject::kGeneratorClosed)));
64
65 // Resume the {receiver} using our trampoline.
66 Callable callable = CodeFactory::ResumeGenerator(isolate());
67 CallStub(callable, context, sent_value, generator, SmiConstant(resume_mode));
68
69 // The resulting Promise is a throwaway, so it doesn't matter what it
70 // resolves to. What is important is that we don't end up keeping the
71 // whole chain of intermediate Promises alive by returning the return value
72 // of ResumeGenerator, as that would create a memory leak.
73 }
74
75 TF_BUILTIN(AsyncFunctionAwaitRejectClosure, AsyncFunctionBuiltinsAssembler) {
76 CSA_ASSERT_JS_ARGC_EQ(this, 1);
77 Node* const sentError = Parameter(1);
78 Node* const context = Parameter(4);
79
80 AsyncFunctionAwaitResumeClosure(context, sentError,
81 JSGeneratorObject::kThrow);
82 Return(UndefinedConstant());
83 }
84
85 TF_BUILTIN(AsyncFunctionAwaitResolveClosure, AsyncFunctionBuiltinsAssembler) {
86 CSA_ASSERT_JS_ARGC_EQ(this, 1);
87 Node* const sentValue = Parameter(1);
88 Node* const context = Parameter(4);
89
90 AsyncFunctionAwaitResumeClosure(context, sentValue, JSGeneratorObject::kNext);
91 Return(UndefinedConstant());
92 }
93
94 // ES#abstract-ops-async-function-await
95 // AsyncFunctionAwait ( value )
96 // Shared logic for the core of await. The parser desugars
97 // await awaited
98 // into
99 // yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise)
100 // The 'awaited' parameter is the value; the generator stands in
101 // for the asyncContext, and .promise is the larger promise under
102 // construction by the enclosing async function.
103 void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
104 Node* const context, Node* const generator, Node* const awaited,
105 Node* const outer_promise, const bool is_predicted_as_caught) {
106 CSA_SLOW_ASSERT(this, HasInstanceType(generator, JS_GENERATOR_OBJECT_TYPE));
107 CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE));
108
109 NodeGenerator1 create_closure_context = [&](Node* native_context) -> Node* {
110 Node* const context =
111 CreatePromiseContext(native_context, AwaitContext::kLength);
112 StoreContextElementNoWriteBarrier(context, AwaitContext::kGeneratorSlot,
113 generator);
114 return context;
115 };
116
117 // TODO(jgruber): AsyncBuiltinsAssembler::Await currently does not reuse
118 // the awaited promise if it is already a promise. Reuse is non-spec compliant
119 // but part of our old behavior gives us a couple of percent
120 // performance boost.
121 // TODO(jgruber): Use a faster specialized version of
122 // InternalPerformPromiseThen.
123
124 Node* const result = Await(
125 context, generator, awaited, outer_promise, create_closure_context,
126 Context::ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN,
127 Context::ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, is_predicted_as_caught);
128
129 Return(result);
130 }
131
132 // Called by the parser from the desugaring of 'await' when catch
133 // prediction indicates that there is a locally surrounding catch block.
134 TF_BUILTIN(AsyncFunctionAwaitCaught, AsyncFunctionBuiltinsAssembler) {
135 CSA_ASSERT_JS_ARGC_EQ(this, 3);
136 Node* const generator = Parameter(1);
137 Node* const awaited = Parameter(2);
138 Node* const outer_promise = Parameter(3);
139 Node* const context = Parameter(6);
140
141 static const bool kIsPredictedAsCaught = true;
142
143 AsyncFunctionAwait(context, generator, awaited, outer_promise,
144 kIsPredictedAsCaught);
145 }
146
147 // Called by the parser from the desugaring of 'await' when catch
148 // prediction indicates no locally surrounding catch block.
149 TF_BUILTIN(AsyncFunctionAwaitUncaught, AsyncFunctionBuiltinsAssembler) {
150 CSA_ASSERT_JS_ARGC_EQ(this, 3);
151 Node* const generator = Parameter(1);
152 Node* const awaited = Parameter(2);
153 Node* const outer_promise = Parameter(3);
154 Node* const context = Parameter(6);
155
156 static const bool kIsPredictedAsCaught = false;
157
158 AsyncFunctionAwait(context, generator, awaited, outer_promise,
159 kIsPredictedAsCaught);
160 }
161
23 TF_BUILTIN(AsyncFunctionPromiseCreate, AsyncFunctionBuiltinsAssembler) { 162 TF_BUILTIN(AsyncFunctionPromiseCreate, AsyncFunctionBuiltinsAssembler) {
24 CSA_ASSERT_JS_ARGC_EQ(this, 0); 163 CSA_ASSERT_JS_ARGC_EQ(this, 0);
25 Node* const context = Parameter(3); 164 Node* const context = Parameter(3);
26 165
27 Node* const promise = AllocateAndInitJSPromise(context); 166 Node* const promise = AllocateAndInitJSPromise(context);
28 167
29 Label if_is_debug_active(this, Label::kDeferred); 168 Label if_is_debug_active(this, Label::kDeferred);
30 GotoIf(IsDebugActive(), &if_is_debug_active); 169 GotoIf(IsDebugActive(), &if_is_debug_active);
31 170
32 // Early exit if debug is not active. 171 // Early exit if debug is not active.
(...skipping 26 matching lines...) Expand all
59 { 198 {
60 // Pop the Promise under construction in an async function on 199 // Pop the Promise under construction in an async function on
61 // from catch prediction stack. 200 // from catch prediction stack.
62 CallRuntime(Runtime::kDebugPopPromise, context); 201 CallRuntime(Runtime::kDebugPopPromise, context);
63 Return(promise); 202 Return(promise);
64 } 203 }
65 } 204 }
66 205
67 } // namespace internal 206 } // namespace internal
68 } // namespace v8 207 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698