| OLD | NEW | 
|---|
| 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 #include "src/code-factory.h" | 7 #include "src/code-factory.h" | 
| 8 #include "src/code-stub-assembler.h" | 8 #include "src/code-stub-assembler.h" | 
| 9 #include "src/promise-utils.h" | 9 #include "src/promise-utils.h" | 
| 10 | 10 | 
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 364                                                       Node* result, | 364                                                       Node* result, | 
| 365                                                       Label* out) { | 365                                                       Label* out) { | 
| 366   Isolate* isolate = this->isolate(); | 366   Isolate* isolate = this->isolate(); | 
| 367 | 367 | 
| 368   Variable var_reason(this, MachineRepresentation::kTagged), | 368   Variable var_reason(this, MachineRepresentation::kTagged), | 
| 369       var_then(this, MachineRepresentation::kTagged); | 369       var_then(this, MachineRepresentation::kTagged); | 
| 370 | 370 | 
| 371   Label do_enqueue(this), fulfill(this), if_cycle(this, Label::kDeferred), | 371   Label do_enqueue(this), fulfill(this), if_cycle(this, Label::kDeferred), | 
| 372       if_rejectpromise(this, Label::kDeferred); | 372       if_rejectpromise(this, Label::kDeferred); | 
| 373 | 373 | 
|  | 374   Label cycle_check(this); | 
|  | 375   GotoUnless(IsPromiseHookEnabled(), &cycle_check); | 
|  | 376   CallRuntime(Runtime::kPromiseHookResolve, context, promise); | 
|  | 377   Goto(&cycle_check); | 
|  | 378 | 
|  | 379   Bind(&cycle_check); | 
| 374   // 6. If SameValue(resolution, promise) is true, then | 380   // 6. If SameValue(resolution, promise) is true, then | 
| 375   GotoIf(SameValue(promise, result, context), &if_cycle); | 381   GotoIf(SameValue(promise, result, context), &if_cycle); | 
| 376 | 382 | 
| 377   // 7. If Type(resolution) is not Object, then | 383   // 7. If Type(resolution) is not Object, then | 
| 378   GotoIf(TaggedIsSmi(result), &fulfill); | 384   GotoIf(TaggedIsSmi(result), &fulfill); | 
| 379   GotoUnless(IsJSReceiver(result), &fulfill); | 385   GotoUnless(IsJSReceiver(result), &fulfill); | 
| 380 | 386 | 
| 381   Label if_nativepromise(this), if_notnativepromise(this, Label::kDeferred); | 387   Label if_nativepromise(this), if_notnativepromise(this, Label::kDeferred); | 
| 382   BranchIfFastPath(context, result, &if_nativepromise, &if_notnativepromise); | 388   BranchIfFastPath(context, result, &if_nativepromise, &if_notnativepromise); | 
| 383 | 389 | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 584          &if_targetismodified); | 590          &if_targetismodified); | 
| 585 | 591 | 
| 586   Variable var_result(this, MachineRepresentation::kTagged), | 592   Variable var_result(this, MachineRepresentation::kTagged), | 
| 587       var_reject_call(this, MachineRepresentation::kTagged), | 593       var_reject_call(this, MachineRepresentation::kTagged), | 
| 588       var_reason(this, MachineRepresentation::kTagged); | 594       var_reason(this, MachineRepresentation::kTagged); | 
| 589 | 595 | 
| 590   Bind(&if_targetisnotmodified); | 596   Bind(&if_targetisnotmodified); | 
| 591   { | 597   { | 
| 592     Node* const instance = AllocateJSPromise(context); | 598     Node* const instance = AllocateJSPromise(context); | 
| 593     var_result.Bind(instance); | 599     var_result.Bind(instance); | 
|  | 600     GotoUnless(IsPromiseHookEnabled(), &init); | 
|  | 601     CallRuntime(Runtime::kPromiseHookInit, context, instance, | 
|  | 602                 UndefinedConstant()); | 
| 594     Goto(&init); | 603     Goto(&init); | 
| 595   } | 604   } | 
| 596 | 605 | 
| 597   Bind(&if_targetismodified); | 606   Bind(&if_targetismodified); | 
| 598   { | 607   { | 
| 599     Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate); | 608     Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate); | 
| 600     Node* const instance = | 609     Node* const instance = | 
| 601         CallStub(fast_new_object_stub, context, promise_fun, new_target); | 610         CallStub(fast_new_object_stub, context, promise_fun, new_target); | 
| 602 | 611 | 
| 603     var_result.Bind(instance); | 612     var_result.Bind(instance); | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 664   Bind(&if_notcallable); | 673   Bind(&if_notcallable); | 
| 665   { | 674   { | 
| 666     Node* const message_id = | 675     Node* const message_id = | 
| 667         SmiConstant(MessageTemplate::kResolverNotAFunction); | 676         SmiConstant(MessageTemplate::kResolverNotAFunction); | 
| 668     CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); | 677     CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); | 
| 669     Return(UndefinedConstant());  // Never reached. | 678     Return(UndefinedConstant());  // Never reached. | 
| 670   } | 679   } | 
| 671 } | 680 } | 
| 672 | 681 | 
| 673 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { | 682 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { | 
| 674   Node* const context = Parameter(3); | 683   Node* const parent = Parameter(1); | 
|  | 684   Node* const context = Parameter(4); | 
| 675   Node* const instance = AllocateJSPromise(context); | 685   Node* const instance = AllocateJSPromise(context); | 
| 676   PromiseInit(instance); | 686   PromiseInit(instance); | 
|  | 687 | 
|  | 688   Label out(this); | 
|  | 689   GotoUnless(IsPromiseHookEnabled(), &out); | 
|  | 690   CallRuntime(Runtime::kPromiseHookInit, context, instance, parent); | 
|  | 691   Goto(&out); | 
|  | 692   Bind(&out); | 
|  | 693 | 
| 677   Return(instance); | 694   Return(instance); | 
| 678 } | 695 } | 
| 679 | 696 | 
| 680 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { | 697 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { | 
| 681   Node* const status = Parameter(1); | 698   Node* const status = Parameter(1); | 
| 682   Node* const result = Parameter(2); | 699   Node* const result = Parameter(2); | 
| 683   Node* const context = Parameter(5); | 700   Node* const context = Parameter(5); | 
| 684 | 701 | 
| 685   Node* const instance = AllocateJSPromise(context); | 702   Node* const instance = AllocateJSPromise(context); | 
| 686   PromiseSet(instance, status, result); | 703   PromiseSet(instance, status, result); | 
|  | 704 | 
|  | 705   Label out(this); | 
|  | 706   GotoUnless(IsPromiseHookEnabled(), &out); | 
|  | 707   CallRuntime(Runtime::kPromiseHookInit, context, instance, | 
|  | 708               UndefinedConstant()); | 
|  | 709   Goto(&out); | 
|  | 710   Bind(&out); | 
| 687   Return(instance); | 711   Return(instance); | 
| 688 } | 712 } | 
| 689 | 713 | 
| 690 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { | 714 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { | 
| 691   Node* const maybe_promise = Parameter(1); | 715   Node* const maybe_promise = Parameter(1); | 
| 692   Label if_notpromise(this, Label::kDeferred); | 716   Label if_notpromise(this, Label::kDeferred); | 
| 693 | 717 | 
| 694   GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); | 718   GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); | 
| 695 | 719 | 
| 696   Node* const result = | 720   Node* const result = | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 745 | 769 | 
| 746   // TODO(gsathya): Remove deferred object and move | 770   // TODO(gsathya): Remove deferred object and move | 
| 747   // NewPromiseCapabability functions to TF. | 771   // NewPromiseCapabability functions to TF. | 
| 748   Bind(&fast_promise_capability); | 772   Bind(&fast_promise_capability); | 
| 749   { | 773   { | 
| 750     // TODO(gsathya): Move this to TF. | 774     // TODO(gsathya): Move this to TF. | 
| 751     Node* const promise_internal_capability = LoadContextElement( | 775     Node* const promise_internal_capability = LoadContextElement( | 
| 752         native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); | 776         native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); | 
| 753     Node* const capability = | 777     Node* const capability = | 
| 754         CallJS(call_callable, context, promise_internal_capability, | 778         CallJS(call_callable, context, promise_internal_capability, | 
| 755                UndefinedConstant()); | 779                UndefinedConstant(), promise); | 
| 756     var_deferred.Bind(capability); | 780     var_deferred.Bind(capability); | 
| 757     Goto(&perform_promise_then); | 781     Goto(&perform_promise_then); | 
| 758   } | 782   } | 
| 759 | 783 | 
| 760   Bind(&promise_capability); | 784   Bind(&promise_capability); | 
| 761   { | 785   { | 
| 762     // TODO(gsathya): Move this to TF. | 786     // TODO(gsathya): Move this to TF. | 
| 763     Node* const new_promise_capability = LoadContextElement( | 787     Node* const new_promise_capability = LoadContextElement( | 
| 764         native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); | 788         native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); | 
| 765     Node* const capability = | 789     Node* const capability = | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 842   } | 866   } | 
| 843 | 867 | 
| 844   Bind(&if_customhandler); | 868   Bind(&if_customhandler); | 
| 845   { | 869   { | 
| 846     CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); | 870     CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); | 
| 847     Return(UndefinedConstant()); | 871     Return(UndefinedConstant()); | 
| 848   } | 872   } | 
| 849 } | 873 } | 
| 850 | 874 | 
| 851 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { | 875 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { | 
|  | 876   Node* const promise = Parameter(1); | 
| 852   Node* const value = Parameter(2); | 877   Node* const value = Parameter(2); | 
| 853   Node* const handler = Parameter(3); | 878   Node* const handler = Parameter(3); | 
| 854   Node* const deferred = Parameter(4); | 879   Node* const deferred = Parameter(4); | 
| 855   Node* const context = Parameter(7); | 880   Node* const context = Parameter(7); | 
| 856   Isolate* isolate = this->isolate(); | 881   Isolate* isolate = this->isolate(); | 
| 857 | 882 | 
| 858   // Get promise from deferred | 883   // Get promise from deferred | 
| 859   // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 884   // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 
| 860   Callable getproperty_callable = CodeFactory::GetProperty(isolate); | 885   Callable getproperty_callable = CodeFactory::GetProperty(isolate); | 
| 861   Node* const key = HeapConstant(isolate->factory()->promise_string()); | 886   Node* const key = HeapConstant(isolate->factory()->promise_string()); | 
| 862   Node* const deferred_promise = | 887   Node* const deferred_promise = | 
| 863       CallStub(getproperty_callable, context, deferred, key); | 888       CallStub(getproperty_callable, context, deferred, key); | 
| 864 | 889 | 
| 865   Variable var_reason(this, MachineRepresentation::kTagged); | 890   Variable var_reason(this, MachineRepresentation::kTagged); | 
| 866 | 891 | 
| 867   Node* const is_debug_active = IsDebugActive(); | 892   Node* const is_debug_active = IsDebugActive(); | 
| 868   Label run_handler(this), if_rejectpromise(this), | 893   Label run_handler(this), if_rejectpromise(this), promisehook_before(this), | 
| 869       debug_push(this, Label::kDeferred), debug_pop(this, Label::kDeferred); | 894       promisehook_after(this), debug_pop(this); | 
| 870   Branch(is_debug_active, &debug_push, &run_handler); |  | 
| 871 | 895 | 
| 872   Bind(&debug_push); | 896   GotoUnless(is_debug_active, &promisehook_before); | 
|  | 897   CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); | 
|  | 898   Goto(&promisehook_before); | 
|  | 899 | 
|  | 900   Bind(&promisehook_before); | 
| 873   { | 901   { | 
| 874     CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); | 902     GotoUnless(IsPromiseHookEnabled(), &run_handler); | 
|  | 903     CallRuntime(Runtime::kPromiseHookBefore, context, promise); | 
| 875     Goto(&run_handler); | 904     Goto(&run_handler); | 
| 876   } | 905   } | 
| 877 | 906 | 
| 878   Bind(&run_handler); | 907   Bind(&run_handler); | 
| 879   { | 908   { | 
| 880     Callable call_callable = CodeFactory::Call(isolate); | 909     Callable call_callable = CodeFactory::Call(isolate); | 
| 881 | 910 | 
| 882     Node* const result = | 911     Node* const result = | 
| 883         CallJS(call_callable, context, handler, UndefinedConstant(), value); | 912         CallJS(call_callable, context, handler, UndefinedConstant(), value); | 
| 884 | 913 | 
| 885     GotoIfException(result, &if_rejectpromise, &var_reason); | 914     GotoIfException(result, &if_rejectpromise, &var_reason); | 
| 886 | 915 | 
| 887     // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 916     // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 
| 888     Node* const key = HeapConstant(isolate->factory()->resolve_string()); | 917     Node* const key = HeapConstant(isolate->factory()->resolve_string()); | 
| 889     Node* const on_resolve = | 918     Node* const on_resolve = | 
| 890         CallStub(getproperty_callable, context, deferred, key); | 919         CallStub(getproperty_callable, context, deferred, key); | 
| 891 | 920 | 
| 892     Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); | 921     Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); | 
| 893     Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); | 922     Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); | 
| 894 | 923 | 
| 895     Bind(&if_internalhandler); | 924     Bind(&if_internalhandler); | 
| 896     InternalResolvePromise(context, deferred_promise, result, &debug_pop); | 925     InternalResolvePromise(context, deferred_promise, result, | 
|  | 926                            &promisehook_after); | 
| 897 | 927 | 
| 898     Bind(&if_customhandler); | 928     Bind(&if_customhandler); | 
| 899     { | 929     { | 
| 900       Node* const maybe_exception = CallJS(call_callable, context, on_resolve, | 930       Node* const maybe_exception = CallJS(call_callable, context, on_resolve, | 
| 901                                            UndefinedConstant(), result); | 931                                            UndefinedConstant(), result); | 
| 902       GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); | 932       GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); | 
| 903       Goto(&debug_pop); | 933       Goto(&promisehook_after); | 
| 904     } | 934     } | 
| 905   } | 935   } | 
| 906 | 936 | 
| 907   Bind(&if_rejectpromise); | 937   Bind(&if_rejectpromise); | 
| 908   { | 938   { | 
| 909     // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 939     // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 
| 910     Node* const key = HeapConstant(isolate->factory()->reject_string()); | 940     Node* const key = HeapConstant(isolate->factory()->reject_string()); | 
| 911     Node* const on_reject = | 941     Node* const on_reject = | 
| 912         CallStub(getproperty_callable, context, deferred, key); | 942         CallStub(getproperty_callable, context, deferred, key); | 
| 913 | 943 | 
| 914     Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); | 944     Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); | 
| 915     CallStub(promise_handle_reject, context, deferred_promise, on_reject, | 945     CallStub(promise_handle_reject, context, deferred_promise, on_reject, | 
| 916              var_reason.value()); | 946              var_reason.value()); | 
|  | 947     Goto(&promisehook_after); | 
|  | 948   } | 
|  | 949 | 
|  | 950   Bind(&promisehook_after); | 
|  | 951   { | 
|  | 952     GotoUnless(IsPromiseHookEnabled(), &debug_pop); | 
|  | 953     CallRuntime(Runtime::kPromiseHookAfter, context, promise); | 
| 917     Goto(&debug_pop); | 954     Goto(&debug_pop); | 
| 918   } | 955   } | 
| 919 | 956 | 
| 920   Bind(&debug_pop); | 957   Bind(&debug_pop); | 
| 921   { | 958   { | 
| 922     Label out(this); | 959     Label out(this); | 
| 923 | 960 | 
| 924     GotoUnless(is_debug_active, &out); | 961     GotoUnless(is_debug_active, &out); | 
| 925     CallRuntime(Runtime::kDebugPopPromise, context); | 962     CallRuntime(Runtime::kDebugPopPromise, context); | 
| 926     Goto(&out); | 963     Goto(&out); | 
| 927 | 964 | 
| 928     Bind(&out); | 965     Bind(&out); | 
| 929     Return(UndefinedConstant()); | 966     Return(UndefinedConstant()); | 
| 930   } | 967   } | 
| 931 } | 968 } | 
| 932 | 969 | 
| 933 }  // namespace internal | 970 }  // namespace internal | 
| 934 }  // namespace v8 | 971 }  // namespace v8 | 
| OLD | NEW | 
|---|