Chromium Code Reviews| 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-promise.h" | 5 #include "src/builtins/builtins-promise.h" |
| 6 #include "src/builtins/builtins-constructor.h" | 6 #include "src/builtins/builtins-constructor.h" |
| 7 #include "src/builtins/builtins-utils.h" | 7 #include "src/builtins/builtins-utils.h" |
| 8 #include "src/builtins/builtins.h" | 8 #include "src/builtins/builtins.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stub-assembler.h" | 10 #include "src/code-stub-assembler.h" |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 897 Heap::kUndefinedValueRootIndex); | 897 Heap::kUndefinedValueRootIndex); |
| 898 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset, | 898 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset, |
| 899 Heap::kUndefinedValueRootIndex); | 899 Heap::kUndefinedValueRootIndex); |
| 900 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, | 900 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, |
| 901 Heap::kUndefinedValueRootIndex); | 901 Heap::kUndefinedValueRootIndex); |
| 902 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, | 902 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, |
| 903 Heap::kUndefinedValueRootIndex); | 903 Heap::kUndefinedValueRootIndex); |
| 904 } | 904 } |
| 905 } | 905 } |
| 906 | 906 |
| 907 void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed( | |
| 908 Node* context, Node* promise_constructor, Node* executor, | |
| 909 Label* if_noaccess) { | |
| 910 Variable var_executor(this, MachineRepresentation::kTagged); | |
| 911 var_executor.Bind(executor); | |
| 912 Label has_access(this), call_runtime(this, Label::kDeferred); | |
| 913 | |
| 914 // If executor is a bound function, load the bound function until we've | |
| 915 // reached an actual function. | |
| 916 Label found_function(this), loop_over_bound_function(this, &var_executor); | |
| 917 Goto(&loop_over_bound_function); | |
| 918 Bind(&loop_over_bound_function); | |
|
gsathya
2017/01/11 17:27:31
i wonder if its better to duplicate the IsJSFuncti
jochen (gone - plz use gerrit)
2017/01/11 18:09:57
afaik that shouldn't make that much of a differenc
Igor Sheludko
2017/01/12 08:31:11
I think it's fine to avoid marking the block as de
| |
| 919 { | |
| 920 GotoIf(IsJSFunction(var_executor.value()), &found_function); | |
| 921 GotoUnless(IsJSBoundFunction(var_executor.value()), &call_runtime); | |
|
Igor Sheludko
2017/01/12 08:31:11
Here you are loading map and then instance type se
| |
| 922 var_executor.Bind(LoadObjectField( | |
| 923 var_executor.value(), JSBoundFunction::kBoundTargetFunctionOffset)); | |
| 924 Goto(&loop_over_bound_function); | |
| 925 } | |
| 926 | |
| 927 // Load the context from the function and compare it to the Promise | |
| 928 // constructor's context. If they match, everything is fine, otherwise, bail | |
| 929 // out to the runtime. | |
| 930 Bind(&found_function); | |
| 931 { | |
| 932 Node* native_context = LoadNativeContext(context); | |
|
gsathya
2017/01/11 17:27:31
this can be an argument to this function, no need
jochen (gone - plz use gerrit)
2017/01/11 18:09:57
done
| |
| 933 Node* function_context = | |
| 934 LoadObjectField(var_executor.value(), JSFunction::kContextOffset); | |
| 935 Node* native_function_context = LoadNativeContext(function_context); | |
| 936 Branch(WordEqual(native_context, native_function_context), &has_access, | |
| 937 &call_runtime); | |
| 938 } | |
| 939 | |
| 940 Bind(&call_runtime); | |
| 941 { | |
| 942 Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context, | |
| 943 promise_constructor), | |
| 944 BooleanConstant(true)), | |
| 945 &has_access, if_noaccess); | |
| 946 } | |
| 947 | |
| 948 Bind(&has_access); | |
| 949 } | |
| 950 | |
| 907 // ES#sec-promise-reject-functions | 951 // ES#sec-promise-reject-functions |
| 908 // Promise Reject Functions | 952 // Promise Reject Functions |
| 909 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { | 953 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { |
| 910 Node* const value = Parameter(1); | 954 Node* const value = Parameter(1); |
| 911 Node* const context = Parameter(4); | 955 Node* const context = Parameter(4); |
| 912 | 956 |
| 913 Label out(this); | 957 Label out(this); |
| 914 | 958 |
| 915 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. | 959 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 916 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; | 960 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 954 | 998 |
| 955 Node* const executor_map = LoadMap(executor); | 999 Node* const executor_map = LoadMap(executor); |
| 956 GotoUnless(IsCallableMap(executor_map), &if_notcallable); | 1000 GotoUnless(IsCallableMap(executor_map), &if_notcallable); |
| 957 | 1001 |
| 958 Node* const native_context = LoadNativeContext(context); | 1002 Node* const native_context = LoadNativeContext(context); |
| 959 Node* const promise_fun = | 1003 Node* const promise_fun = |
| 960 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); | 1004 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); |
| 961 Node* const is_debug_active = IsDebugActive(); | 1005 Node* const is_debug_active = IsDebugActive(); |
| 962 Label if_targetisnotmodified(this), | 1006 Label if_targetisnotmodified(this), |
| 963 if_targetismodified(this, Label::kDeferred), run_executor(this), | 1007 if_targetismodified(this, Label::kDeferred), run_executor(this), |
| 964 debug_push(this); | 1008 debug_push(this), if_noaccess(this, Label::kDeferred); |
| 1009 | |
| 1010 BranchIfAccessCheckFailed(context, promise_fun, executor, &if_noaccess); | |
| 965 | 1011 |
| 966 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified, | 1012 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified, |
| 967 &if_targetismodified); | 1013 &if_targetismodified); |
| 968 | 1014 |
| 969 Variable var_result(this, MachineRepresentation::kTagged), | 1015 Variable var_result(this, MachineRepresentation::kTagged), |
| 970 var_reject_call(this, MachineRepresentation::kTagged), | 1016 var_reject_call(this, MachineRepresentation::kTagged), |
| 971 var_reason(this, MachineRepresentation::kTagged); | 1017 var_reason(this, MachineRepresentation::kTagged); |
| 972 | 1018 |
| 973 Bind(&if_targetisnotmodified); | 1019 Bind(&if_targetisnotmodified); |
| 974 { | 1020 { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1039 } | 1085 } |
| 1040 | 1086 |
| 1041 // 2. If IsCallable(executor) is false, throw a TypeError exception. | 1087 // 2. If IsCallable(executor) is false, throw a TypeError exception. |
| 1042 Bind(&if_notcallable); | 1088 Bind(&if_notcallable); |
| 1043 { | 1089 { |
| 1044 Node* const message_id = | 1090 Node* const message_id = |
| 1045 SmiConstant(MessageTemplate::kResolverNotAFunction); | 1091 SmiConstant(MessageTemplate::kResolverNotAFunction); |
| 1046 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); | 1092 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); |
| 1047 Return(UndefinedConstant()); // Never reached. | 1093 Return(UndefinedConstant()); // Never reached. |
| 1048 } | 1094 } |
| 1095 | |
| 1096 // Silently fail if the stack looks fishy. | |
| 1097 Bind(&if_noaccess); | |
| 1098 { | |
| 1099 Node* const counter_id = | |
| 1100 SmiConstant(v8::Isolate::kPromiseConstructorReturnedUndefined); | |
| 1101 CallRuntime(Runtime::kCountUsage, context, counter_id); | |
| 1102 Return(UndefinedConstant()); | |
| 1103 } | |
| 1049 } | 1104 } |
| 1050 | 1105 |
| 1051 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { | 1106 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { |
| 1052 Node* const parent = Parameter(1); | 1107 Node* const parent = Parameter(1); |
| 1053 Node* const context = Parameter(4); | 1108 Node* const context = Parameter(4); |
| 1054 Return(AllocateAndInitJSPromise(context, parent)); | 1109 Return(AllocateAndInitJSPromise(context, parent)); |
| 1055 } | 1110 } |
| 1056 | 1111 |
| 1057 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { | 1112 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { |
| 1058 Node* const maybe_promise = Parameter(1); | 1113 Node* const maybe_promise = Parameter(1); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1449 | 1504 |
| 1450 // 5. Return promiseCapability.[[Promise]]. | 1505 // 5. Return promiseCapability.[[Promise]]. |
| 1451 Node* const promise = | 1506 Node* const promise = |
| 1452 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset); | 1507 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset); |
| 1453 Return(promise); | 1508 Return(promise); |
| 1454 } | 1509 } |
| 1455 } | 1510 } |
| 1456 | 1511 |
| 1457 } // namespace internal | 1512 } // namespace internal |
| 1458 } // namespace v8 | 1513 } // namespace v8 |
| OLD | NEW |