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

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

Issue 2590563003: [promises] Remove deferred object (Closed)
Patch Set: add comments Created 3 years, 12 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
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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-promise.h" 5 #include "src/builtins/builtins-promise.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-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/promise-utils.h" 10 #include "src/promise-utils.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 typedef compiler::Node Node; 15 typedef compiler::Node Node;
16 typedef CodeStubAssembler::ParameterMode ParameterMode; 16 typedef CodeStubAssembler::ParameterMode ParameterMode;
17 typedef compiler::CodeAssemblerState CodeAssemblerState; 17 typedef compiler::CodeAssemblerState CodeAssemblerState;
18 18
19 Node* PromiseBuiltinsAssembler::AllocateAndInitPromise(Node* context,
20 Node* parent) {
21 Node* const instance = AllocateJSPromise(context);
22 PromiseInit(instance);
23
24 Label out(this);
25 GotoUnless(IsPromiseHookEnabled(), &out);
26 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
27 Goto(&out);
28
29 Bind(&out);
30 return instance;
31 }
32
19 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( 33 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
20 Node* promise, Node* debug_event, Node* native_context) { 34 Node* promise, Node* debug_event, Node* native_context) {
21 Node* const context = 35 Node* const context =
22 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength)); 36 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength));
23 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex); 37 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
24 StoreObjectFieldNoWriteBarrier( 38 StoreObjectFieldNoWriteBarrier(
25 context, FixedArray::kLengthOffset, 39 context, FixedArray::kLengthOffset,
26 SmiConstant(PromiseUtils::kPromiseContextLength)); 40 SmiConstant(PromiseUtils::kPromiseContextLength));
27 41
28 Node* const empty_fn = 42 Node* const empty_fn =
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 Node* const promise_fun = 208 Node* const promise_fun =
195 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); 209 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
196 210
197 // 3. Let C be ? SpeciesConstructor(promise, %Promise%). 211 // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
198 Node* constructor = SpeciesConstructor(context, promise, promise_fun); 212 Node* constructor = SpeciesConstructor(context, promise, promise_fun);
199 213
200 // 4. Let resultCapability be ? NewPromiseCapability(C). 214 // 4. Let resultCapability be ? NewPromiseCapability(C).
201 Callable call_callable = CodeFactory::Call(isolate); 215 Callable call_callable = CodeFactory::Call(isolate);
202 Label fast_promise_capability(this), promise_capability(this), 216 Label fast_promise_capability(this), promise_capability(this),
203 perform_promise_then(this); 217 perform_promise_then(this);
204 Variable var_deferred(this, MachineRepresentation::kTagged); 218 Variable var_deferred_promise(this, MachineRepresentation::kTagged),
219 var_deferred_on_resolve(this, MachineRepresentation::kTagged),
220 var_deferred_on_reject(this, MachineRepresentation::kTagged);
205 221
206 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, 222 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
207 &promise_capability); 223 &promise_capability);
208 224
209 // TODO(gsathya): Remove deferred object and move
210 // NewPromiseCapabability functions to TF.
211 Bind(&fast_promise_capability); 225 Bind(&fast_promise_capability);
212 { 226 {
213 // TODO(gsathya): Move this to TF. 227 Node* const deferred_promise = AllocateAndInitPromise(context, promise);
214 Node* const promise_internal_capability = LoadContextElement( 228 PromiseInit(deferred_promise);
215 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); 229 var_deferred_promise.Bind(deferred_promise);
216 Node* const capability = 230 var_deferred_on_resolve.Bind(UndefinedConstant());
217 CallJS(call_callable, context, promise_internal_capability, 231 var_deferred_on_reject.Bind(UndefinedConstant());
218 UndefinedConstant(), promise);
219 var_deferred.Bind(capability);
220 Goto(&perform_promise_then); 232 Goto(&perform_promise_then);
221 } 233 }
222 234
223 Bind(&promise_capability); 235 Bind(&promise_capability);
224 { 236 {
225 // TODO(gsathya): Move this to TF. 237 // TODO(gsathya): Move this to TF.
226 Node* const new_promise_capability = LoadContextElement( 238 Node* const new_promise_capability = LoadContextElement(
227 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); 239 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
228 Node* const capability = 240 Node* const deferred =
229 CallJS(call_callable, context, new_promise_capability, 241 CallJS(call_callable, context, new_promise_capability,
230 UndefinedConstant(), constructor); 242 UndefinedConstant(), constructor);
231 var_deferred.Bind(capability); 243 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
244 Node* key = HeapConstant(isolate->factory()->promise_string());
245 Node* const deferred_promise =
246 CallStub(getproperty_callable, context, deferred, key);
247 var_deferred_promise.Bind(deferred_promise);
248
249 key = HeapConstant(isolate->factory()->resolve_string());
250 Node* const deferred_on_resolve =
251 CallStub(getproperty_callable, context, deferred, key);
252 var_deferred_on_resolve.Bind(deferred_on_resolve);
253
254 key = HeapConstant(isolate->factory()->reject_string());
255 Node* const deferred_on_reject =
256 CallStub(getproperty_callable, context, deferred, key);
257 var_deferred_on_reject.Bind(deferred_on_reject);
258
232 Goto(&perform_promise_then); 259 Goto(&perform_promise_then);
233 } 260 }
234 261
235 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, 262 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
236 // resultCapability). 263 // resultCapability).
237 Bind(&perform_promise_then); 264 Bind(&perform_promise_then);
238 Node* const result = InternalPerformPromiseThen( 265 Node* const result = InternalPerformPromiseThen(
239 context, promise, on_resolve, on_reject, var_deferred.value()); 266 context, promise, on_resolve, on_reject, var_deferred_promise.value(),
267 var_deferred_on_resolve.value(), var_deferred_on_reject.value());
240 return result; 268 return result;
241 } 269 }
242 270
243 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(Node* context, 271 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
244 Node* promise, 272 Node* context, Node* promise, Node* on_resolve, Node* on_reject,
245 Node* on_resolve, 273 Node* deferred_promise, Node* deferred_on_resolve,
246 Node* on_reject, 274 Node* deferred_on_reject) {
247 Node* deferred) {
248 Node* const native_context = LoadNativeContext(context); 275 Node* const native_context = LoadNativeContext(context);
249 276
250 Variable var_on_resolve(this, MachineRepresentation::kTagged), 277 Variable var_on_resolve(this, MachineRepresentation::kTagged),
251 var_on_reject(this, MachineRepresentation::kTagged); 278 var_on_reject(this, MachineRepresentation::kTagged);
252 279
253 var_on_resolve.Bind(on_resolve); 280 var_on_resolve.Bind(on_resolve);
254 var_on_reject.Bind(on_reject); 281 var_on_reject.Bind(on_reject);
255 282
256 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this), 283 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this),
257 append_callbacks(this); 284 append_callbacks(this);
(...skipping 27 matching lines...) Expand all
285 } 312 }
286 } 313 }
287 314
288 Bind(&append_callbacks); 315 Bind(&append_callbacks);
289 { 316 {
290 Label fulfilled_check(this); 317 Label fulfilled_check(this);
291 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset); 318 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset);
292 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)), 319 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)),
293 &fulfilled_check); 320 &fulfilled_check);
294 321
295 Node* const existing_deferred = 322 Node* const existing_deferred_promise =
296 LoadObjectField(promise, JSPromise::kDeferredOffset); 323 LoadObjectField(promise, JSPromise::kDeferredPromiseOffset);
297 324
298 Label if_noexistingcallbacks(this), if_existingcallbacks(this); 325 Label if_noexistingcallbacks(this), if_existingcallbacks(this);
299 Branch(IsUndefined(existing_deferred), &if_noexistingcallbacks, 326 Branch(IsUndefined(existing_deferred_promise), &if_noexistingcallbacks,
300 &if_existingcallbacks); 327 &if_existingcallbacks);
301 328
302 Bind(&if_noexistingcallbacks); 329 Bind(&if_noexistingcallbacks);
303 { 330 {
304 // Store callbacks directly in the slots. 331 // Store callbacks directly in the slots.
305 StoreObjectField(promise, JSPromise::kDeferredOffset, deferred); 332 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
333 deferred_promise);
334 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
335 deferred_on_resolve);
336 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
337 deferred_on_reject);
306 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 338 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
307 var_on_resolve.value()); 339 var_on_resolve.value());
308 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 340 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
309 var_on_reject.value()); 341 var_on_reject.value());
310 Goto(&out); 342 Goto(&out);
311 } 343 }
312 344
313 Bind(&if_existingcallbacks); 345 Bind(&if_existingcallbacks);
314 { 346 {
315 Label if_singlecallback(this), if_multiplecallbacks(this); 347 Label if_singlecallback(this), if_multiplecallbacks(this);
316 BranchIfJSObject(existing_deferred, &if_singlecallback, 348 BranchIfJSObject(existing_deferred_promise, &if_singlecallback,
317 &if_multiplecallbacks); 349 &if_multiplecallbacks);
318 350
319 Bind(&if_singlecallback); 351 Bind(&if_singlecallback);
320 { 352 {
321 // Create new FixedArrays to store callbacks, and migrate 353 // Create new FixedArrays to store callbacks, and migrate
322 // existing callbacks. 354 // existing callbacks.
323 Node* const deferreds = 355 Node* const deferred_promise_arr =
324 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 356 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
325 StoreFixedArrayElement(deferreds, 0, existing_deferred); 357 StoreFixedArrayElement(deferred_promise_arr, 0,
326 StoreFixedArrayElement(deferreds, 1, deferred); 358 existing_deferred_promise);
359 StoreFixedArrayElement(deferred_promise_arr, 1, deferred_promise);
360
361 Node* const deferred_on_resolve_arr =
362 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
Igor Sheludko 2016/12/28 06:56:45 BTW, we have Tuple2 and Tuple3 structs.
gsathya 2016/12/29 19:48:17 Hmm, but these can grow to length > 3
363 StoreFixedArrayElement(
364 deferred_on_resolve_arr, 0,
365 LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset));
366 StoreFixedArrayElement(deferred_on_resolve_arr, 1, deferred_on_resolve);
367
368 Node* const deferred_on_reject_arr =
369 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
370 StoreFixedArrayElement(
371 deferred_on_reject_arr, 0,
372 LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset));
373 StoreFixedArrayElement(deferred_on_reject_arr, 1, deferred_on_reject);
327 374
328 Node* const fulfill_reactions = 375 Node* const fulfill_reactions =
329 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 376 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
330 StoreFixedArrayElement( 377 StoreFixedArrayElement(
331 fulfill_reactions, 0, 378 fulfill_reactions, 0,
332 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset)); 379 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset));
333 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value()); 380 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value());
334 381
335 Node* const reject_reactions = 382 Node* const reject_reactions =
336 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 383 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
337 StoreFixedArrayElement( 384 StoreFixedArrayElement(
338 reject_reactions, 0, 385 reject_reactions, 0,
339 LoadObjectField(promise, JSPromise::kRejectReactionsOffset)); 386 LoadObjectField(promise, JSPromise::kRejectReactionsOffset));
340 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value()); 387 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value());
341 388
342 // Store new FixedArrays in promise. 389 // Store new FixedArrays in promise.
343 StoreObjectField(promise, JSPromise::kDeferredOffset, deferreds); 390 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
391 deferred_promise_arr);
392 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
393 deferred_on_resolve_arr);
394 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
395 deferred_on_reject_arr);
344 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 396 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
345 fulfill_reactions); 397 fulfill_reactions);
346 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 398 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
347 reject_reactions); 399 reject_reactions);
348 Goto(&out); 400 Goto(&out);
349 } 401 }
350 402
351 Bind(&if_multiplecallbacks); 403 Bind(&if_multiplecallbacks);
352 { 404 {
353 AppendPromiseCallback(JSPromise::kDeferredOffset, promise, deferred); 405 AppendPromiseCallback(JSPromise::kDeferredPromiseOffset, promise,
406 deferred_promise);
407 AppendPromiseCallback(JSPromise::kDeferredOnResolveOffset, promise,
408 deferred_on_resolve);
409 AppendPromiseCallback(JSPromise::kDeferredOnRejectOffset, promise,
410 deferred_on_reject);
354 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise, 411 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise,
355 var_on_resolve.value()); 412 var_on_resolve.value());
356 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, 413 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise,
357 var_on_reject.value()); 414 var_on_reject.value());
358 Goto(&out); 415 Goto(&out);
359 } 416 }
360 } 417 }
361 418
362 Bind(&fulfilled_check); 419 Bind(&fulfilled_check);
363 { 420 {
364 Label reject(this); 421 Label reject(this);
365 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); 422 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset);
366 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)), 423 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)),
367 &reject); 424 &reject);
368 425
369 // TODO(gsathya): Move this to TF. 426 Node* info = AllocatePromiseReactionJobInfo(
370 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, 427 promise, result, var_on_resolve.value(), deferred_promise,
371 var_on_resolve.value(), deferred, 428 deferred_on_resolve, deferred_on_reject, context);
429 // TODO(gsathya): Move this to TF
430 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
372 SmiConstant(v8::Promise::kFulfilled)); 431 SmiConstant(v8::Promise::kFulfilled));
373 Goto(&out); 432 Goto(&out);
374 433
375 Bind(&reject); 434 Bind(&reject);
376 { 435 {
377 Node* const has_handler = PromiseHasHandler(promise); 436 Node* const has_handler = PromiseHasHandler(promise);
378 Label enqueue(this); 437 Label enqueue(this);
379 438
380 // TODO(gsathya): Fold these runtime calls and move to TF. 439 // TODO(gsathya): Fold these runtime calls and move to TF.
381 GotoIf(has_handler, &enqueue); 440 GotoIf(has_handler, &enqueue);
382 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); 441 CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
383 Goto(&enqueue); 442 Goto(&enqueue);
384 443
385 Bind(&enqueue); 444 Bind(&enqueue);
386 { 445 {
387 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, 446 Node* info = AllocatePromiseReactionJobInfo(
388 result, var_on_reject.value(), deferred, 447 promise, result, var_on_reject.value(), deferred_promise,
448 deferred_on_resolve, deferred_on_reject, context);
449 // TODO(gsathya): Move this to TF
450 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
389 SmiConstant(v8::Promise::kRejected)); 451 SmiConstant(v8::Promise::kRejected));
390
391 Goto(&out); 452 Goto(&out);
392 } 453 }
393 } 454 }
394 } 455 }
395 } 456 }
396 457
397 Bind(&out); 458 Bind(&out);
398 PromiseSetHasHandler(promise); 459 PromiseSetHasHandler(promise);
399 460 return deferred_promise;
400 // TODO(gsathya): This call will be removed once we don't have to
401 // deal with deferred objects.
402 Isolate* isolate = this->isolate();
403 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
404 Node* const key =
405 HeapConstant(isolate->factory()->NewStringFromAsciiChecked("promise"));
406 Node* const result = CallStub(getproperty_callable, context, deferred, key);
407
408 return result;
409 } 461 }
410 462
411 // Promise fast path implementations rely on unmodified JSPromise instances. 463 // Promise fast path implementations rely on unmodified JSPromise instances.
412 // We use a fairly coarse granularity for this and simply check whether both 464 // We use a fairly coarse granularity for this and simply check whether both
413 // the promise itself is unmodified (i.e. its map has not changed) and its 465 // the promise itself is unmodified (i.e. its map has not changed) and its
414 // prototype is unmodified. 466 // prototype is unmodified.
415 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp 467 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
416 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, 468 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
417 Label* if_isunmodified, 469 Label* if_isunmodified,
418 Label* if_ismodified) { 470 Label* if_ismodified) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 Node* const key = 602 Node* const key =
551 HeapConstant(isolate->factory()->promise_handled_by_symbol()); 603 HeapConstant(isolate->factory()->promise_handled_by_symbol());
552 CallRuntime(Runtime::kSetProperty, context, result, key, promise, 604 CallRuntime(Runtime::kSetProperty, context, result, key, promise,
553 SmiConstant(STRICT)); 605 SmiConstant(STRICT));
554 Goto(&enqueue); 606 Goto(&enqueue);
555 607
556 // 12. Perform EnqueueJob("PromiseJobs", 608 // 12. Perform EnqueueJob("PromiseJobs",
557 // PromiseResolveThenableJob, « promise, resolution, thenAction 609 // PromiseResolveThenableJob, « promise, resolution, thenAction
558 // »). 610 // »).
559 Bind(&enqueue); 611 Bind(&enqueue);
612 // TODO(gsathya): Move this to TF
560 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, 613 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise,
561 result, var_then.value()); 614 result, var_then.value());
562 Goto(&out); 615 Goto(&out);
563 } 616 }
564 617
565 // 7.b Return FulfillPromise(promise, resolution). 618 // 7.b Return FulfillPromise(promise, resolution).
566 Bind(&fulfill); 619 Bind(&fulfill);
567 { 620 {
568 CallRuntime(Runtime::kPromiseFulfill, context, promise, 621 CallRuntime(Runtime::kPromiseFulfill, context, promise,
569 SmiConstant(v8::Promise::kFulfilled), result); 622 SmiConstant(v8::Promise::kFulfilled), result);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 Node* const message_id = 812 Node* const message_id =
760 SmiConstant(MessageTemplate::kResolverNotAFunction); 813 SmiConstant(MessageTemplate::kResolverNotAFunction);
761 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 814 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
762 Return(UndefinedConstant()); // Never reached. 815 Return(UndefinedConstant()); // Never reached.
763 } 816 }
764 } 817 }
765 818
766 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { 819 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
767 Node* const parent = Parameter(1); 820 Node* const parent = Parameter(1);
768 Node* const context = Parameter(4); 821 Node* const context = Parameter(4);
769 Node* const instance = AllocateJSPromise(context); 822 Return(AllocateAndInitPromise(context, parent));
770 PromiseInit(instance);
771
772 Label out(this);
773 GotoUnless(IsPromiseHookEnabled(), &out);
774 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
775 Goto(&out);
776 Bind(&out);
777
778 Return(instance);
779 } 823 }
780 824
781 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { 825 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
782 Node* const status = Parameter(1); 826 Node* const status = Parameter(1);
783 Node* const result = Parameter(2); 827 Node* const result = Parameter(2);
784 Node* const context = Parameter(5); 828 Node* const context = Parameter(5);
785 829
786 Node* const instance = AllocateJSPromise(context); 830 Node* const instance = AllocateJSPromise(context);
787 PromiseSet(instance, status, result); 831 PromiseSet(instance, status, result);
788 832
(...skipping 17 matching lines...) Expand all
806 Return(result); 850 Return(result);
807 851
808 Bind(&if_notpromise); 852 Bind(&if_notpromise);
809 Return(FalseConstant()); 853 Return(FalseConstant());
810 } 854 }
811 855
812 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { 856 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
813 Node* const promise = Parameter(1); 857 Node* const promise = Parameter(1);
814 Node* const on_resolve = Parameter(2); 858 Node* const on_resolve = Parameter(2);
815 Node* const on_reject = Parameter(3); 859 Node* const on_reject = Parameter(3);
816 Node* const deferred = Parameter(4); 860 Node* const deferred_promise = Parameter(4);
817 Node* const context = Parameter(7); 861 Node* const context = Parameter(7);
818 862
819 Node* const result = InternalPerformPromiseThen(context, promise, on_resolve, 863 // No deferred_on_resolve/deferred_on_reject because this is just an
820 on_reject, deferred); 864 // internal promise created by async-await.
865 Node* const result = InternalPerformPromiseThen(
866 context, promise, on_resolve, on_reject, deferred_promise,
867 UndefinedConstant(), UndefinedConstant());
821 868
822 // TODO(gsathya): This is unused, but value is returned according to spec. 869 // TODO(gsathya): This is unused, but value is returned according to spec.
823 Return(result); 870 Return(result);
824 } 871 }
825 872
826 // ES#sec-promise.prototype.then 873 // ES#sec-promise.prototype.then
827 // Promise.prototype.catch ( onFulfilled, onRejected ) 874 // Promise.prototype.catch ( onFulfilled, onRejected )
828 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) { 875 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) {
829 // 1. Let promise be the this value. 876 // 1. Let promise be the this value.
830 Node* const promise = Parameter(0); 877 Node* const promise = Parameter(0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 { 950 {
904 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); 951 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
905 Return(UndefinedConstant()); 952 Return(UndefinedConstant());
906 } 953 }
907 } 954 }
908 955
909 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { 956 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
910 Node* const promise = Parameter(1); 957 Node* const promise = Parameter(1);
911 Node* const value = Parameter(2); 958 Node* const value = Parameter(2);
912 Node* const handler = Parameter(3); 959 Node* const handler = Parameter(3);
913 Node* const deferred = Parameter(4); 960 Node* const deferred_promise = Parameter(4);
914 Node* const context = Parameter(7); 961 Node* const deferred_on_resolve = Parameter(5);
962 Node* const deferred_on_reject = Parameter(6);
963 Node* const context = Parameter(9);
915 Isolate* isolate = this->isolate(); 964 Isolate* isolate = this->isolate();
916 965
917 // Get promise from deferred
918 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
919 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
920 Node* const key = HeapConstant(isolate->factory()->promise_string());
921 Node* const deferred_promise =
922 CallStub(getproperty_callable, context, deferred, key);
923
924 Variable var_reason(this, MachineRepresentation::kTagged); 966 Variable var_reason(this, MachineRepresentation::kTagged);
925 967
926 Node* const is_debug_active = IsDebugActive(); 968 Node* const is_debug_active = IsDebugActive();
927 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), 969 Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
928 promisehook_after(this), debug_pop(this); 970 promisehook_after(this), debug_pop(this);
929 971
930 GotoUnless(is_debug_active, &promisehook_before); 972 GotoUnless(is_debug_active, &promisehook_before);
931 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 973 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
932 Goto(&promisehook_before); 974 Goto(&promisehook_before);
933 975
934 Bind(&promisehook_before); 976 Bind(&promisehook_before);
935 { 977 {
936 GotoUnless(IsPromiseHookEnabled(), &run_handler); 978 GotoUnless(IsPromiseHookEnabled(), &run_handler);
937 CallRuntime(Runtime::kPromiseHookBefore, context, promise); 979 CallRuntime(Runtime::kPromiseHookBefore, context, promise);
938 Goto(&run_handler); 980 Goto(&run_handler);
939 } 981 }
940 982
941 Bind(&run_handler); 983 Bind(&run_handler);
942 { 984 {
943 Callable call_callable = CodeFactory::Call(isolate); 985 Callable call_callable = CodeFactory::Call(isolate);
944
945 Node* const result = 986 Node* const result =
946 CallJS(call_callable, context, handler, UndefinedConstant(), value); 987 CallJS(call_callable, context, handler, UndefinedConstant(), value);
947 988
948 GotoIfException(result, &if_rejectpromise, &var_reason); 989 GotoIfException(result, &if_rejectpromise, &var_reason);
949 990
950 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
951 Node* const key = HeapConstant(isolate->factory()->resolve_string());
952 Node* const on_resolve =
953 CallStub(getproperty_callable, context, deferred, key);
954
955 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 991 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
956 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 992 Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
993 &if_customhandler);
957 994
958 Bind(&if_internalhandler); 995 Bind(&if_internalhandler);
959 InternalResolvePromise(context, deferred_promise, result); 996 InternalResolvePromise(context, deferred_promise, result);
960 Goto(&promisehook_after); 997 Goto(&promisehook_after);
961 998
962 Bind(&if_customhandler); 999 Bind(&if_customhandler);
963 { 1000 {
964 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, 1001 Node* const maybe_exception =
965 UndefinedConstant(), result); 1002 CallJS(call_callable, context, deferred_on_resolve,
1003 UndefinedConstant(), result);
966 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 1004 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
967 Goto(&promisehook_after); 1005 Goto(&promisehook_after);
968 } 1006 }
969 } 1007 }
970 1008
971 Bind(&if_rejectpromise); 1009 Bind(&if_rejectpromise);
972 { 1010 {
973 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
974 Node* const key = HeapConstant(isolate->factory()->reject_string());
975 Node* const on_reject =
976 CallStub(getproperty_callable, context, deferred, key);
977
978 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 1011 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
979 CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1012 CallStub(promise_handle_reject, context, deferred_promise,
980 var_reason.value()); 1013 deferred_on_reject, var_reason.value());
981 Goto(&promisehook_after); 1014 Goto(&promisehook_after);
982 } 1015 }
983 1016
984 Bind(&promisehook_after); 1017 Bind(&promisehook_after);
985 { 1018 {
986 GotoUnless(IsPromiseHookEnabled(), &debug_pop); 1019 GotoUnless(IsPromiseHookEnabled(), &debug_pop);
987 CallRuntime(Runtime::kPromiseHookAfter, context, promise); 1020 CallRuntime(Runtime::kPromiseHookAfter, context, promise);
988 Goto(&debug_pop); 1021 Goto(&debug_pop);
989 } 1022 }
990 1023
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 CallStub(getproperty_callable, context, promise, then_str); 1062 CallStub(getproperty_callable, context, promise, then_str);
1030 Callable call_callable = CodeFactory::Call(isolate); 1063 Callable call_callable = CodeFactory::Call(isolate);
1031 Node* const result = 1064 Node* const result =
1032 CallJS(call_callable, context, then, promise, on_resolve, on_reject); 1065 CallJS(call_callable, context, then, promise, on_resolve, on_reject);
1033 Return(result); 1066 Return(result);
1034 } 1067 }
1035 } 1068 }
1036 1069
1037 } // namespace internal 1070 } // namespace internal
1038 } // namespace v8 1071 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698