@@ -13,6 +13,58 @@ namespace internal {
1313
1414using compiler::Node;
1515
16+ void AsyncBuiltinsAssembler::Await (Node* context, Node* generator, Node* value,
17+ Node* outer_promise,
18+ Builtins::Name fulfill_builtin,
19+ Builtins::Name reject_builtin,
20+ Node* is_predicted_as_caught) {
21+ CSA_SLOW_ASSERT (this , Word32Or (IsJSAsyncGeneratorObject (generator),
22+ IsJSGeneratorObject (generator)));
23+ CSA_SLOW_ASSERT (this , IsJSPromise (outer_promise));
24+ CSA_SLOW_ASSERT (this , IsBoolean (is_predicted_as_caught));
25+
26+ Node* const native_context = LoadNativeContext (context);
27+
28+ // TODO(bmeurer): This could be optimized and folded into a single allocation.
29+ Node* const promise = AllocateAndInitJSPromise (native_context);
30+ Node* const promise_reactions =
31+ LoadObjectField (promise, JSPromise::kReactionsOrResultOffset );
32+ Node* const fulfill_handler =
33+ HeapConstant (Builtins::CallableFor (isolate (), fulfill_builtin).code ());
34+ Node* const reject_handler =
35+ HeapConstant (Builtins::CallableFor (isolate (), reject_builtin).code ());
36+ Node* const reaction = AllocatePromiseReaction (
37+ promise_reactions, generator, fulfill_handler, reject_handler);
38+ StoreObjectField (promise, JSPromise::kReactionsOrResultOffset , reaction);
39+ PromiseSetHasHandler (promise);
40+
41+ // Perform ! Call(promiseCapability.[[Resolve]], undefined, « value »).
42+ CallBuiltin (Builtins::kResolvePromise , native_context, promise, value);
43+
44+ // When debugging, we need to link from the {generator} to the
45+ // {outer_promise} of the async function/generator.
46+ Label done (this );
47+ GotoIfNot (IsDebugActive (), &done);
48+ CallRuntime (Runtime::kSetProperty , native_context, generator,
49+ LoadRoot (Heap::kgenerator_outer_promise_symbolRootIndex),
50+ outer_promise, SmiConstant (LanguageMode::kStrict ));
51+ GotoIf (IsFalse (is_predicted_as_caught), &done);
52+ GotoIf (TaggedIsSmi (value), &done);
53+ GotoIfNot (IsJSPromise (value), &done);
54+ PromiseSetHandledHint (value);
55+ Goto (&done);
56+ BIND (&done);
57+ }
58+
59+ void AsyncBuiltinsAssembler::Await (Node* context, Node* generator, Node* value,
60+ Node* outer_promise,
61+ Builtins::Name fulfill_builtin,
62+ Builtins::Name reject_builtin,
63+ bool is_predicted_as_caught) {
64+ return Await (context, generator, value, outer_promise, fulfill_builtin,
65+ reject_builtin, BooleanConstant (is_predicted_as_caught));
66+ }
67+
1668namespace {
1769// Describe fields of Context associated with the AsyncIterator unwrap closure.
1870class ValueUnwrapContext {
@@ -22,162 +74,6 @@ class ValueUnwrapContext {
2274
2375} // namespace
2476
25- Node* AsyncBuiltinsAssembler::Await (
26- Node* context, Node* generator, Node* value, Node* outer_promise,
27- int context_length, const ContextInitializer& init_closure_context,
28- Node* on_resolve_context_index, Node* on_reject_context_index,
29- Node* is_predicted_as_caught) {
30- DCHECK_GE (context_length, Context::MIN_CONTEXT_SLOTS);
31-
32- Node* const native_context = LoadNativeContext (context);
33-
34- static const int kWrappedPromiseOffset = FixedArray::SizeFor (context_length);
35- static const int kThrowawayPromiseOffset =
36- kWrappedPromiseOffset + JSPromise::kSizeWithEmbedderFields ;
37- static const int kResolveClosureOffset =
38- kThrowawayPromiseOffset + JSPromise::kSizeWithEmbedderFields ;
39- static const int kRejectClosureOffset =
40- kResolveClosureOffset + JSFunction::kSizeWithoutPrototype ;
41- static const int kTotalSize =
42- kRejectClosureOffset + JSFunction::kSizeWithoutPrototype ;
43-
44- Node* const base = AllocateInNewSpace (kTotalSize );
45- Node* const closure_context = base;
46- {
47- // Initialize closure context
48- InitializeFunctionContext (native_context, closure_context, context_length);
49- init_closure_context (closure_context);
50- }
51-
52- // Let promiseCapability be ! NewPromiseCapability(%Promise%).
53- Node* const promise_fun =
54- LoadContextElement (native_context, Context::PROMISE_FUNCTION_INDEX);
55- CSA_ASSERT (this , IsFunctionWithPrototypeSlotMap (LoadMap (promise_fun)));
56- Node* const promise_map =
57- LoadObjectField (promise_fun, JSFunction::kPrototypeOrInitialMapOffset );
58- // Assert that the JSPromise map has an instance size is
59- // JSPromise::kSizeWithEmbedderFields.
60- CSA_ASSERT (this , WordEqual (LoadMapInstanceSizeInWords (promise_map),
61- IntPtrConstant (JSPromise::kSizeWithEmbedderFields /
62- kPointerSize )));
63- Node* const wrapped_value = InnerAllocate (base, kWrappedPromiseOffset );
64- {
65- // Initialize Promise
66- StoreMapNoWriteBarrier (wrapped_value, promise_map);
67- InitializeJSObjectFromMap (
68- wrapped_value, promise_map,
69- IntPtrConstant (JSPromise::kSizeWithEmbedderFields ));
70- PromiseInit (wrapped_value);
71- }
72-
73- Node* const throwaway = InnerAllocate (base, kThrowawayPromiseOffset );
74- {
75- // Initialize throwawayPromise
76- StoreMapNoWriteBarrier (throwaway, promise_map);
77- InitializeJSObjectFromMap (
78- throwaway, promise_map,
79- IntPtrConstant (JSPromise::kSizeWithEmbedderFields ));
80- PromiseInit (throwaway);
81- }
82-
83- Node* const on_resolve = InnerAllocate (base, kResolveClosureOffset );
84- {
85- // Initialize resolve handler
86- InitializeNativeClosure (closure_context, native_context, on_resolve,
87- on_resolve_context_index);
88- }
89-
90- Node* const on_reject = InnerAllocate (base, kRejectClosureOffset );
91- {
92- // Initialize reject handler
93- InitializeNativeClosure (closure_context, native_context, on_reject,
94- on_reject_context_index);
95- }
96-
97- {
98- // Add PromiseHooks if needed
99- Label next (this );
100- GotoIfNot (IsPromiseHookEnabledOrDebugIsActive (), &next);
101- CallRuntime (Runtime::kPromiseHookInit , context, wrapped_value,
102- outer_promise);
103- CallRuntime (Runtime::kPromiseHookInit , context, throwaway, wrapped_value);
104- Goto (&next);
105- BIND (&next);
106- }
107-
108- // Perform ! Call(promiseCapability.[[Resolve]], undefined, « promise »).
109- CallBuiltin (Builtins::kResolvePromise , context, wrapped_value, value);
110-
111- // The Promise will be thrown away and not handled, but it shouldn't trigger
112- // unhandled reject events as its work is done
113- PromiseSetHasHandler (throwaway);
114-
115- Label do_perform_promise_then (this );
116- GotoIfNot (IsDebugActive (), &do_perform_promise_then);
117- {
118- Label common (this );
119- GotoIf (TaggedIsSmi (value), &common);
120- GotoIfNot (HasInstanceType (value, JS_PROMISE_TYPE), &common);
121- {
122- // Mark the reject handler callback to be a forwarding edge, rather
123- // than a meaningful catch handler
124- Node* const key =
125- HeapConstant (factory ()->promise_forwarding_handler_symbol ());
126- CallRuntime (Runtime::kSetProperty , context, on_reject, key,
127- TrueConstant (), SmiConstant (LanguageMode::kStrict ));
128-
129- GotoIf (IsFalse (is_predicted_as_caught), &common);
130- PromiseSetHandledHint (value);
131- }
132-
133- Goto (&common);
134- BIND (&common);
135- // Mark the dependency to outer Promise in case the throwaway Promise is
136- // found on the Promise stack
137- CSA_SLOW_ASSERT (this , HasInstanceType (outer_promise, JS_PROMISE_TYPE));
138-
139- Node* const key = HeapConstant (factory ()->promise_handled_by_symbol ());
140- CallRuntime (Runtime::kSetProperty , context, throwaway, key, outer_promise,
141- SmiConstant (LanguageMode::kStrict ));
142- }
143-
144- Goto (&do_perform_promise_then);
145- BIND (&do_perform_promise_then);
146- return CallBuiltin (Builtins::kPerformPromiseThen , context, wrapped_value,
147- on_resolve, on_reject, throwaway);
148- }
149-
150- void AsyncBuiltinsAssembler::InitializeNativeClosure (Node* context,
151- Node* native_context,
152- Node* function,
153- Node* context_index) {
154- Node* const function_map = LoadContextElement (
155- native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
156- // Ensure that we don't have to initialize prototype_or_initial_map field of
157- // JSFunction.
158- CSA_ASSERT (this , WordEqual (LoadMapInstanceSizeInWords (function_map),
159- IntPtrConstant (JSFunction::kSizeWithoutPrototype /
160- kPointerSize )));
161- STATIC_ASSERT (JSFunction::kSizeWithoutPrototype == 7 * kPointerSize );
162- StoreMapNoWriteBarrier (function, function_map);
163- StoreObjectFieldRoot (function, JSObject::kPropertiesOrHashOffset ,
164- Heap::kEmptyFixedArrayRootIndex );
165- StoreObjectFieldRoot (function, JSObject::kElementsOffset ,
166- Heap::kEmptyFixedArrayRootIndex );
167- StoreObjectFieldRoot (function, JSFunction::kFeedbackVectorOffset ,
168- Heap::kUndefinedCellRootIndex );
169-
170- Node* shared_info = LoadContextElement (native_context, context_index);
171- CSA_ASSERT (this , IsSharedFunctionInfo (shared_info));
172- StoreObjectFieldNoWriteBarrier (
173- function, JSFunction::kSharedFunctionInfoOffset , shared_info);
174- StoreObjectFieldNoWriteBarrier (function, JSFunction::kContextOffset , context);
175-
176- Node* const code =
177- LoadObjectField (shared_info, SharedFunctionInfo::kCodeOffset );
178- StoreObjectFieldNoWriteBarrier (function, JSFunction::kCodeOffset , code);
179- }
180-
18177Node* AsyncBuiltinsAssembler::CreateUnwrapClosure (Node* native_context,
18278 Node* done) {
18379 Node* const map = LoadContextElement (
0 commit comments