OLD | NEW |
| (Empty) |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/builtins/builtins-async.h" | |
6 #include "src/builtins/builtins-utils.h" | |
7 #include "src/builtins/builtins.h" | |
8 #include "src/code-factory.h" | |
9 #include "src/code-stub-assembler.h" | |
10 #include "src/frames-inl.h" | |
11 | |
12 namespace v8 { | |
13 namespace internal { | |
14 | |
15 Node* AsyncBuiltinsAssembler::Await( | |
16 Node* context, Node* generator, Node* value, Node* outer_promise, | |
17 const NodeGenerator1& create_closure_context, int on_resolve_context_index, | |
18 int on_reject_context_index, bool is_predicted_as_caught) { | |
19 // Let promiseCapability be ! NewPromiseCapability(%Promise%). | |
20 Node* const wrapped_value = AllocateAndInitJSPromise(context); | |
21 | |
22 // Perform ! Call(promiseCapability.[[Resolve]], undefined, « promise »). | |
23 InternalResolvePromise(context, wrapped_value, value); | |
24 | |
25 Node* const native_context = LoadNativeContext(context); | |
26 | |
27 Node* const closure_context = create_closure_context(native_context); | |
28 Node* const map = LoadContextElement( | |
29 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); | |
30 | |
31 // Load and allocate on_resolve closure | |
32 Node* const on_resolve_shared_fun = | |
33 LoadContextElement(native_context, on_resolve_context_index); | |
34 CSA_SLOW_ASSERT( | |
35 this, HasInstanceType(on_resolve_shared_fun, SHARED_FUNCTION_INFO_TYPE)); | |
36 Node* const on_resolve = AllocateFunctionWithMapAndContext( | |
37 map, on_resolve_shared_fun, closure_context); | |
38 | |
39 // Load and allocate on_reject closure | |
40 Node* const on_reject_shared_fun = | |
41 LoadContextElement(native_context, on_reject_context_index); | |
42 CSA_SLOW_ASSERT( | |
43 this, HasInstanceType(on_reject_shared_fun, SHARED_FUNCTION_INFO_TYPE)); | |
44 Node* const on_reject = AllocateFunctionWithMapAndContext( | |
45 map, on_reject_shared_fun, closure_context); | |
46 | |
47 Node* const throwaway_promise = | |
48 AllocateAndInitJSPromise(context, wrapped_value); | |
49 | |
50 // The Promise will be thrown away and not handled, but it shouldn't trigger | |
51 // unhandled reject events as its work is done | |
52 PromiseSetHasHandler(throwaway_promise); | |
53 | |
54 Label do_perform_promise_then(this); | |
55 GotoIfNot(IsDebugActive(), &do_perform_promise_then); | |
56 { | |
57 Label common(this); | |
58 GotoIf(TaggedIsSmi(value), &common); | |
59 GotoIfNot(HasInstanceType(value, JS_PROMISE_TYPE), &common); | |
60 { | |
61 // Mark the reject handler callback to be a forwarding edge, rather | |
62 // than a meaningful catch handler | |
63 Node* const key = | |
64 HeapConstant(factory()->promise_forwarding_handler_symbol()); | |
65 CallRuntime(Runtime::kSetProperty, context, on_reject, key, | |
66 TrueConstant(), SmiConstant(STRICT)); | |
67 | |
68 if (is_predicted_as_caught) PromiseSetHandledHint(value); | |
69 } | |
70 | |
71 Goto(&common); | |
72 Bind(&common); | |
73 // Mark the dependency to outer Promise in case the throwaway Promise is | |
74 // found on the Promise stack | |
75 CSA_SLOW_ASSERT(this, HasInstanceType(outer_promise, JS_PROMISE_TYPE)); | |
76 | |
77 Node* const key = HeapConstant(factory()->promise_handled_by_symbol()); | |
78 CallRuntime(Runtime::kSetProperty, context, throwaway_promise, key, | |
79 outer_promise, SmiConstant(STRICT)); | |
80 } | |
81 | |
82 Goto(&do_perform_promise_then); | |
83 Bind(&do_perform_promise_then); | |
84 InternalPerformPromiseThen(context, wrapped_value, on_resolve, on_reject, | |
85 throwaway_promise, UndefinedConstant(), | |
86 UndefinedConstant()); | |
87 | |
88 return wrapped_value; | |
89 } | |
90 | |
91 } // namespace internal | |
92 } // namespace v8 | |
OLD | NEW |