• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Await(Node * context,Node * generator,Node * value,Node * outer_promise,const NodeGenerator1 & create_closure_context,int on_resolve_context_index,int on_reject_context_index,bool is_predicted_as_caught)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
93