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

Side by Side Diff: src/builtins/builtins-promise.cc

Issue 2497523002: [promises] Move promise constructor to TFS (Closed)
Patch Set: add goto Created 4 years 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 2016 the V8 project authors. All rights reserved. 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 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-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 7
8 #include "src/code-factory.h"
8 #include "src/promise-utils.h" 9 #include "src/promise-utils.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 13
13 // ES#sec-promise-resolve-functions 14 // ES#sec-promise-resolve-functions
14 // Promise Resolve Functions 15 // Promise Resolve Functions
15 BUILTIN(PromiseResolveClosure) { 16 BUILTIN(PromiseResolveClosure) {
16 HandleScope scope(isolate); 17 HandleScope scope(isolate);
17 18
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 &resolve, &reject); 74 &resolve, &reject);
74 75
75 Handle<FixedArray> result = isolate->factory()->NewFixedArray(2); 76 Handle<FixedArray> result = isolate->factory()->NewFixedArray(2);
76 result->set(0, *resolve); 77 result->set(0, *resolve);
77 result->set(1, *reject); 78 result->set(1, *reject);
78 79
79 return *isolate->factory()->NewJSArrayWithElements(result, FAST_ELEMENTS, 2, 80 return *isolate->factory()->NewJSArrayWithElements(result, FAST_ELEMENTS, 2,
80 NOT_TENURED); 81 NOT_TENURED);
81 } 82 }
82 83
84 void Builtins::Generate_PromiseConstructor(
85 compiler::CodeAssemblerState* state) {
86 CodeStubAssembler a(state);
87 typedef CodeStubAssembler::Variable Variable;
88 typedef CodeStubAssembler::Label Label;
89 typedef compiler::Node Node;
90
91 Node* const executor = a.Parameter(1);
92 Node* const new_target = a.Parameter(2);
93 Node* const context = a.Parameter(4);
94 Isolate* isolate = a.isolate();
95
96 Label if_targetisundefined(&a, Label::kDeferred);
97
98 a.GotoIf(a.WordEqual(new_target, a.UndefinedConstant()),
99 &if_targetisundefined);
100
101 Label if_notcallable(&a, Label::kDeferred);
102
103 a.GotoIf(a.TaggedIsSmi(executor), &if_notcallable);
104
105 Node* const executor_map = a.LoadMap(executor);
106 a.GotoUnless(a.IsCallableMap(executor_map), &if_notcallable);
107
108 Node* const native_context = a.LoadNativeContext(context);
109 Node* const promise_fun =
110 a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
111
112 Label if_targetisnotmodified(&a), if_targetismodified(&a, Label::kDeferred),
113 run_executor(&a), debug_push(&a, Label::kDeferred);
114 a.Branch(a.WordEqual(promise_fun, new_target), &if_targetisnotmodified,
115 &if_targetismodified);
116
117 Variable var_result(&a, MachineRepresentation::kTagged),
118 var_reject_call(&a, MachineRepresentation::kTagged),
119 var_reason(&a, MachineRepresentation::kTagged);
120
121 a.Bind(&if_targetisnotmodified);
122 {
123 Node* const initial_map = a.LoadObjectField(
124 promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
125
126 Node* const instance = a.AllocateJSObjectFromMap(initial_map);
127 var_result.Bind(instance);
128 a.Branch(a.IsDebugActive(), &debug_push, &run_executor);
129 }
130
131 a.Bind(&if_targetismodified);
132 {
133 Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate);
jgruber 2016/11/24 07:42:30 Perhaps Benedikt can chime in whether the usage of
134 Node* const instance =
135 a.CallStub(fast_new_object_stub, context, promise_fun, new_target);
136
137 var_result.Bind(instance);
138 a.Branch(a.IsDebugActive(), &debug_push, &run_executor);
139 }
140
141 a.Bind(&debug_push);
142 {
143 a.CallRuntime(Runtime::kDebugPushPromise, context, var_result.value());
144 a.Goto(&run_executor);
145 }
146
147 a.Bind(&run_executor);
148 {
149 Label out(&a), if_rejectpromise(&a), debug_pop(&a, Label::kDeferred);
150
151 Node* const key =
152 a.HeapConstant(a.isolate()->factory()->promise_state_symbol());
153 Node* const value = a.SmiConstant(kPromisePending);
154 Node* const language_mode = a.SmiConstant(STRICT);
155 a.CallRuntime(Runtime::kSetProperty, context, var_result.value(), key,
156 value, language_mode);
157 Node* const resolving_functions = a.CallRuntime(
158 Runtime::kCreateResolvingFunctions, context, var_result.value());
159 Node* const resolve =
160 a.LoadFixedArrayElement(resolving_functions, a.IntPtrConstant(0));
161 Node* const reject =
162 a.LoadFixedArrayElement(resolving_functions, a.IntPtrConstant(1));
163 Callable call_callable = CodeFactory::Call(isolate);
164
165 Node* const maybe_exception =
166 a.CallJS(call_callable, context, executor, a.UndefinedConstant(),
167 resolve, reject);
168
169 a.GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
170 a.Branch(a.IsDebugActive(), &debug_pop, &out);
171
172 a.Bind(&if_rejectpromise);
173 {
174 Callable call_callable = CodeFactory::Call(isolate);
175 a.CallJS(call_callable, context, reject, a.UndefinedConstant(),
176 var_reason.value());
177 a.Branch(a.IsDebugActive(), &debug_pop, &out);
178 }
179
180 a.Bind(&debug_pop);
181 {
182 a.CallRuntime(Runtime::kDebugPopPromise, context);
183 a.Goto(&out);
184 }
185 a.Bind(&out);
186 a.Return(var_result.value());
187 }
188
189 // 1. If NewTarget is undefined, throw a TypeError exception.
190 a.Bind(&if_targetisundefined);
191 {
192 Node* const message_id = a.SmiConstant(MessageTemplate::kNotAPromise);
193 a.CallRuntime(Runtime::kThrowTypeError, context, message_id, new_target);
194 a.Return(a.UndefinedConstant()); // Never reached.
195 }
196
197 // 2. If IsCallable(executor) is false, throw a TypeError exception.
198 a.Bind(&if_notcallable);
199 {
200 Node* const message_id =
201 a.SmiConstant(MessageTemplate::kResolverNotAFunction);
202 a.CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
203 a.Return(a.UndefinedConstant()); // Never reached.
204 }
205 }
206
207 void Builtins::Generate_PromiseInternalConstructor(
208 compiler::CodeAssemblerState* state) {
209 typedef compiler::Node Node;
210 CodeStubAssembler a(state);
211
212 Node* const context = a.Parameter(3);
213 Node* const native_context = a.LoadNativeContext(context);
214 Node* const promise_fun =
215 a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
216 Node* const initial_map =
217 a.LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
218 Node* const instance = a.AllocateJSObjectFromMap(initial_map);
219 a.Return(instance);
220 }
221
222 // TODO(gsathya): Refactor promise.js::IsPromise to use this.
223 void Builtins::Generate_IsPromise(compiler::CodeAssemblerState* state) {
224 CodeStubAssembler a(state);
225 typedef compiler::Node Node;
226 typedef CodeStubAssembler::Label Label;
227
228 Node* const maybe_promise = a.Parameter(1);
229 Label if_ispromise(&a), if_isnotpromise(&a, Label::kDeferred);
230 a.GotoIf(a.TaggedIsSmi(maybe_promise), &if_isnotpromise);
231
232 Node* const maybe_promise_type =
233 a.LoadMapInstanceType(a.LoadMap(maybe_promise));
234
235 a.Branch(a.Word32Equal(maybe_promise_type, a.Int32Constant(JS_PROMISE_TYPE)),
236 &if_ispromise, &if_isnotpromise);
237
238 a.Bind(&if_ispromise);
239 a.Return(a.BooleanConstant(true));
240
241 a.Bind(&if_isnotpromise);
242 a.Return(a.BooleanConstant(false));
243 }
244
83 } // namespace internal 245 } // namespace internal
84 } // namespace v8 246 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/contexts.h » ('j') | src/factory.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698