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

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

Issue 2575313002: [promisehook] Implement PromiseHook (Closed)
Patch Set: remove promise_hook_enabled_ 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 #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
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 // ES#sec-promise-reject-functions 14 // ES#sec-promise-reject-functions
15 // Promise Reject Functions 15 // Promise Reject Functions
16 BUILTIN(PromiseRejectClosure) { 16 BUILTIN(PromiseRejectClosure) {
17 HandleScope scope(isolate); 17 HandleScope scope(isolate);
18 18
19 Handle<Context> context(isolate->context(), isolate); 19 Handle<Context> context(isolate->context(), isolate);
20 20
21 if (PromiseUtils::HasAlreadyVisited(context)) { 21 if (PromiseUtils::HasAlreadyVisited(context)) {
22 return isolate->heap()->undefined_value(); 22 return isolate->heap()->undefined_value();
23 } 23 }
24 24
25 PromiseUtils::SetAlreadyVisited(context); 25 PromiseUtils::SetAlreadyVisited(context);
26 Handle<Object> value = args.atOrUndefined(isolate, 1); 26 Handle<Object> value = args.atOrUndefined(isolate, 1);
27 Handle<JSObject> promise = handle(PromiseUtils::GetPromise(context), isolate); 27 Handle<JSPromise> promise =
28 handle(PromiseUtils::GetPromise(context), isolate);
28 Handle<Object> debug_event = 29 Handle<Object> debug_event =
29 handle(PromiseUtils::GetDebugEvent(context), isolate); 30 handle(PromiseUtils::GetDebugEvent(context), isolate);
30 MaybeHandle<Object> maybe_result; 31 MaybeHandle<Object> maybe_result;
31 Handle<Object> argv[] = {promise, value, debug_event}; 32 Handle<Object> argv[] = {promise, value, debug_event};
33
34 isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
35 isolate->factory()->undefined_value());
36
32 RETURN_FAILURE_ON_EXCEPTION( 37 RETURN_FAILURE_ON_EXCEPTION(
33 isolate, Execution::Call(isolate, isolate->promise_internal_reject(), 38 isolate, Execution::Call(isolate, isolate->promise_internal_reject(),
34 isolate->factory()->undefined_value(), 39 isolate->factory()->undefined_value(),
35 arraysize(argv), argv)); 40 arraysize(argv), argv));
36 return isolate->heap()->undefined_value(); 41 return isolate->heap()->undefined_value();
37 } 42 }
38 43
39 // ES#sec-createresolvingfunctions 44 // ES#sec-createresolvingfunctions
40 // CreateResolvingFunctions ( promise ) 45 // CreateResolvingFunctions ( promise )
41 BUILTIN(CreateResolvingFunctions) { 46 BUILTIN(CreateResolvingFunctions) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 &if_targetismodified); 96 &if_targetismodified);
92 97
93 Variable var_result(&a, MachineRepresentation::kTagged), 98 Variable var_result(&a, MachineRepresentation::kTagged),
94 var_reject_call(&a, MachineRepresentation::kTagged), 99 var_reject_call(&a, MachineRepresentation::kTagged),
95 var_reason(&a, MachineRepresentation::kTagged); 100 var_reason(&a, MachineRepresentation::kTagged);
96 101
97 a.Bind(&if_targetisnotmodified); 102 a.Bind(&if_targetisnotmodified);
98 { 103 {
99 Node* const instance = a.AllocateJSPromise(context); 104 Node* const instance = a.AllocateJSPromise(context);
100 var_result.Bind(instance); 105 var_result.Bind(instance);
106 a.GotoUnless(a.IsPromiseHookEnabled(), &init);
107 a.CallRuntime(Runtime::kPromiseHookInit, context, instance,
108 a.UndefinedConstant());
101 a.Goto(&init); 109 a.Goto(&init);
102 } 110 }
103 111
104 a.Bind(&if_targetismodified); 112 a.Bind(&if_targetismodified);
105 { 113 {
106 Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate); 114 Callable fast_new_object_stub = CodeFactory::FastNewObject(isolate);
107 Node* const instance = 115 Node* const instance =
108 a.CallStub(fast_new_object_stub, context, promise_fun, new_target); 116 a.CallStub(fast_new_object_stub, context, promise_fun, new_target);
109 117
110 var_result.Bind(instance); 118 var_result.Bind(instance);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 Node* const message_id = 182 Node* const message_id =
175 a.SmiConstant(MessageTemplate::kResolverNotAFunction); 183 a.SmiConstant(MessageTemplate::kResolverNotAFunction);
176 a.CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 184 a.CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
177 a.Return(a.UndefinedConstant()); // Never reached. 185 a.Return(a.UndefinedConstant()); // Never reached.
178 } 186 }
179 } 187 }
180 188
181 void Builtins::Generate_PromiseInternalConstructor( 189 void Builtins::Generate_PromiseInternalConstructor(
182 compiler::CodeAssemblerState* state) { 190 compiler::CodeAssemblerState* state) {
183 typedef compiler::Node Node; 191 typedef compiler::Node Node;
192 typedef CodeStubAssembler::Label Label;
184 CodeStubAssembler a(state); 193 CodeStubAssembler a(state);
185 194
186 Node* const context = a.Parameter(3); 195 Node* const parent = a.Parameter(1);
196 Node* const context = a.Parameter(4);
187 Node* const instance = a.AllocateJSPromise(context); 197 Node* const instance = a.AllocateJSPromise(context);
188 a.PromiseInit(instance); 198 a.PromiseInit(instance);
199
200 Label out(&a);
201 a.GotoUnless(a.IsPromiseHookEnabled(), &out);
202 a.CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
203 a.Goto(&out);
204 a.Bind(&out);
189 a.Return(instance); 205 a.Return(instance);
190 } 206 }
191 207
192 void Builtins::Generate_PromiseCreateAndSet( 208 void Builtins::Generate_PromiseCreateAndSet(
193 compiler::CodeAssemblerState* state) { 209 compiler::CodeAssemblerState* state) {
194 typedef compiler::Node Node; 210 typedef compiler::Node Node;
211 typedef CodeStubAssembler::Label Label;
195 CodeStubAssembler a(state); 212 CodeStubAssembler a(state);
196 213
197 Node* const status = a.Parameter(1); 214 Node* const status = a.Parameter(1);
198 Node* const result = a.Parameter(2); 215 Node* const result = a.Parameter(2);
199 Node* const context = a.Parameter(5); 216 Node* const context = a.Parameter(5);
200 217
201 Node* const instance = a.AllocateJSPromise(context); 218 Node* const instance = a.AllocateJSPromise(context);
202 a.PromiseSet(instance, status, result); 219 a.PromiseSet(instance, status, result);
220
221 Label out(&a);
222 a.GotoUnless(a.IsPromiseHookEnabled(), &out);
223 a.CallRuntime(Runtime::kPromiseHookInit, context, instance,
224 a.UndefinedConstant());
225 a.Goto(&out);
226 a.Bind(&out);
203 a.Return(instance); 227 a.Return(instance);
204 } 228 }
205 229
206 namespace { 230 namespace {
207 231
208 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate, 232 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate,
209 compiler::Node* context, 233 compiler::Node* context,
210 compiler::Node* value, 234 compiler::Node* value,
211 MessageTemplate::Template msg_template) { 235 MessageTemplate::Template msg_template) {
212 typedef compiler::Node Node; 236 typedef compiler::Node Node;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 621
598 // TODO(gsathya): Remove deferred object and move 622 // TODO(gsathya): Remove deferred object and move
599 // NewPromiseCapbability functions to TF. 623 // NewPromiseCapbability functions to TF.
600 a.Bind(&fast_promise_capability); 624 a.Bind(&fast_promise_capability);
601 { 625 {
602 // TODO(gsathya): Move this to TF. 626 // TODO(gsathya): Move this to TF.
603 Node* const promise_internal_capability = a.LoadContextElement( 627 Node* const promise_internal_capability = a.LoadContextElement(
604 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); 628 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX);
605 Node* const capability = 629 Node* const capability =
606 a.CallJS(call_callable, context, promise_internal_capability, 630 a.CallJS(call_callable, context, promise_internal_capability,
607 a.UndefinedConstant()); 631 a.UndefinedConstant(), promise);
608 var_deferred.Bind(capability); 632 var_deferred.Bind(capability);
609 a.Goto(&perform_promise_then); 633 a.Goto(&perform_promise_then);
610 } 634 }
611 635
612 a.Bind(&promise_capability); 636 a.Bind(&promise_capability);
613 { 637 {
614 // TODO(gsathya): Move this to TF. 638 // TODO(gsathya): Move this to TF.
615 Node* const new_promise_capability = a.LoadContextElement( 639 Node* const new_promise_capability = a.LoadContextElement(
616 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); 640 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
617 Node* const capability = 641 Node* const capability =
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 // 4. If alreadyResolved.[[Value]] is true, return undefined. 863 // 4. If alreadyResolved.[[Value]] is true, return undefined.
840 a.GotoIf(a.SmiEqual(has_already_visited, a.SmiConstant(1)), &out); 864 a.GotoIf(a.SmiEqual(has_already_visited, a.SmiConstant(1)), &out);
841 865
842 // 5.Set alreadyResolved.[[Value]] to true. 866 // 5.Set alreadyResolved.[[Value]] to true.
843 a.StoreFixedArrayElement(context, has_already_visited_slot, a.SmiConstant(1)); 867 a.StoreFixedArrayElement(context, has_already_visited_slot, a.SmiConstant(1));
844 868
845 // 2. Let promise be F.[[Promise]]. 869 // 2. Let promise be F.[[Promise]].
846 Node* const promise = a.LoadFixedArrayElement( 870 Node* const promise = a.LoadFixedArrayElement(
847 context, a.IntPtrConstant(PromiseUtils::kPromiseSlot)); 871 context, a.IntPtrConstant(PromiseUtils::kPromiseSlot));
848 872
873 Label run_resolve(&a);
874 a.GotoUnless(a.IsPromiseHookEnabled(), &run_resolve);
875 a.CallRuntime(Runtime::kPromiseHookResolve, context, promise);
876 a.Goto(&run_resolve);
877
878 a.Bind(&run_resolve);
849 InternalResolvePromise(&a, context, promise, value, &out); 879 InternalResolvePromise(&a, context, promise, value, &out);
850 880
851 a.Bind(&out); 881 a.Bind(&out);
852 a.Return(a.UndefinedConstant()); 882 a.Return(a.UndefinedConstant());
853 } 883 }
854 884
855 void Builtins::Generate_ResolvePromise(compiler::CodeAssemblerState* state) { 885 void Builtins::Generate_ResolvePromise(compiler::CodeAssemblerState* state) {
856 CodeStubAssembler a(state); 886 CodeStubAssembler a(state);
857 typedef compiler::Node Node; 887 typedef compiler::Node Node;
858 typedef CodeStubAssembler::Label Label; 888 typedef CodeStubAssembler::Label Label;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 a.Return(a.UndefinedConstant()); 932 a.Return(a.UndefinedConstant());
903 } 933 }
904 } 934 }
905 935
906 void Builtins::Generate_PromiseHandle(compiler::CodeAssemblerState* state) { 936 void Builtins::Generate_PromiseHandle(compiler::CodeAssemblerState* state) {
907 CodeStubAssembler a(state); 937 CodeStubAssembler a(state);
908 typedef compiler::Node Node; 938 typedef compiler::Node Node;
909 typedef CodeStubAssembler::Label Label; 939 typedef CodeStubAssembler::Label Label;
910 typedef CodeStubAssembler::Variable Variable; 940 typedef CodeStubAssembler::Variable Variable;
911 941
942 Node* const promise = a.Parameter(1);
912 Node* const value = a.Parameter(2); 943 Node* const value = a.Parameter(2);
913 Node* const handler = a.Parameter(3); 944 Node* const handler = a.Parameter(3);
914 Node* const deferred = a.Parameter(4); 945 Node* const deferred = a.Parameter(4);
915 Node* const context = a.Parameter(7); 946 Node* const context = a.Parameter(7);
916 Isolate* isolate = a.isolate(); 947 Isolate* isolate = a.isolate();
917 948
918 // Get promise from deferred 949 // Get promise from deferred
919 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 950 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
920 Callable getproperty_callable = CodeFactory::GetProperty(isolate); 951 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
921 Node* const key = a.HeapConstant(isolate->factory()->promise_string()); 952 Node* const key = a.HeapConstant(isolate->factory()->promise_string());
922 Node* const deferred_promise = 953 Node* const deferred_promise =
923 a.CallStub(getproperty_callable, context, deferred, key); 954 a.CallStub(getproperty_callable, context, deferred, key);
924 955
925 Variable var_reason(&a, MachineRepresentation::kTagged); 956 Variable var_reason(&a, MachineRepresentation::kTagged);
926 957
927 Node* const is_debug_active = a.IsDebugActive(); 958 Node* const is_debug_active = a.IsDebugActive();
928 Label run_handler(&a), if_rejectpromise(&a), debug_push(&a, Label::kDeferred), 959 Label run_handler(&a), if_rejectpromise(&a), debug_push(&a, Label::kDeferred),
929 debug_pop(&a, Label::kDeferred); 960 debug_pop(&a), promisehook_after(&a);
930 a.Branch(is_debug_active, &debug_push, &run_handler); 961
962 a.GotoUnless(a.IsPromiseHookEnabled(), &debug_push);
963 a.CallRuntime(Runtime::kPromiseHookBefore, context, promise);
964 a.Goto(&debug_push);
931 965
932 a.Bind(&debug_push); 966 a.Bind(&debug_push);
933 { 967 {
968 a.GotoUnless(is_debug_active, &run_handler);
934 a.CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 969 a.CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
935 a.Goto(&run_handler); 970 a.Goto(&run_handler);
936 } 971 }
937 972
938 a.Bind(&run_handler); 973 a.Bind(&run_handler);
939 { 974 {
940 Callable call_callable = CodeFactory::Call(isolate); 975 Callable call_callable = CodeFactory::Call(isolate);
941 976
942 Node* const result = 977 Node* const result =
943 a.CallJS(call_callable, context, handler, a.UndefinedConstant(), value); 978 a.CallJS(call_callable, context, handler, a.UndefinedConstant(), value);
944 979
945 a.GotoIfException(result, &if_rejectpromise, &var_reason); 980 a.GotoIfException(result, &if_rejectpromise, &var_reason);
946 981
947 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 982 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
948 Node* const key = a.HeapConstant(isolate->factory()->resolve_string()); 983 Node* const key = a.HeapConstant(isolate->factory()->resolve_string());
949 Node* const on_resolve = 984 Node* const on_resolve =
950 a.CallStub(getproperty_callable, context, deferred, key); 985 a.CallStub(getproperty_callable, context, deferred, key);
951 986
952 Label if_internalhandler(&a), if_customhandler(&a, Label::kDeferred); 987 Label if_internalhandler(&a), if_customhandler(&a, Label::kDeferred);
953 a.Branch(a.IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 988 a.Branch(a.IsUndefined(on_resolve), &if_internalhandler, &if_customhandler);
954 989
955 a.Bind(&if_internalhandler); 990 a.Bind(&if_internalhandler);
956 InternalResolvePromise(&a, context, deferred_promise, result, &debug_pop); 991 InternalResolvePromise(&a, context, deferred_promise, result,
992 &promisehook_after);
957 993
958 a.Bind(&if_customhandler); 994 a.Bind(&if_customhandler);
959 { 995 {
960 Node* const maybe_exception = a.CallJS(call_callable, context, on_resolve, 996 Node* const maybe_exception = a.CallJS(call_callable, context, on_resolve,
961 a.UndefinedConstant(), result); 997 a.UndefinedConstant(), result);
962 a.GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 998 a.GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
963 a.Goto(&debug_pop); 999 a.Goto(&promisehook_after);
964 } 1000 }
965 } 1001 }
966 1002
967 a.Bind(&if_rejectpromise); 1003 a.Bind(&if_rejectpromise);
968 { 1004 {
969 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 1005 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
970 Node* const key = a.HeapConstant(isolate->factory()->reject_string()); 1006 Node* const key = a.HeapConstant(isolate->factory()->reject_string());
971 Node* const on_reject = 1007 Node* const on_reject =
972 a.CallStub(getproperty_callable, context, deferred, key); 1008 a.CallStub(getproperty_callable, context, deferred, key);
973 1009
974 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 1010 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
975 a.CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1011 a.CallStub(promise_handle_reject, context, deferred_promise, on_reject,
976 var_reason.value()); 1012 var_reason.value());
1013 a.Goto(&promisehook_after);
1014 }
1015
1016 a.Bind(&promisehook_after);
1017 {
1018 a.GotoUnless(a.IsPromiseHookEnabled(), &debug_pop);
1019 a.CallRuntime(Runtime::kPromiseHookAfter, context, promise);
977 a.Goto(&debug_pop); 1020 a.Goto(&debug_pop);
978 } 1021 }
979 1022
980 a.Bind(&debug_pop); 1023 a.Bind(&debug_pop);
981 { 1024 {
982 Label out(&a); 1025 Label out(&a);
983
984 a.GotoUnless(is_debug_active, &out); 1026 a.GotoUnless(is_debug_active, &out);
985 a.CallRuntime(Runtime::kDebugPopPromise, context); 1027 a.CallRuntime(Runtime::kDebugPopPromise, context);
986 a.Goto(&out); 1028 a.Goto(&out);
987 1029
988 a.Bind(&out); 1030 a.Bind(&out);
989 a.Return(a.UndefinedConstant()); 1031 a.Return(a.UndefinedConstant());
990 } 1032 }
991 } 1033 }
992 1034
993 } // namespace internal 1035 } // namespace internal
994 } // namespace v8 1036 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-stub-assembler.cc » ('j') | src/code-stub-assembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698