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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 2893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2904 Int32Constant(0)); | 2904 Int32Constant(0)); |
2905 } | 2905 } |
2906 | 2906 |
2907 Node* CodeStubAssembler::IsCallableMap(Node* map) { | 2907 Node* CodeStubAssembler::IsCallableMap(Node* map) { |
2908 CSA_ASSERT(this, IsMap(map)); | 2908 CSA_ASSERT(this, IsMap(map)); |
2909 return Word32NotEqual( | 2909 return Word32NotEqual( |
2910 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsCallable)), | 2910 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsCallable)), |
2911 Int32Constant(0)); | 2911 Int32Constant(0)); |
2912 } | 2912 } |
2913 | 2913 |
| 2914 Node* CodeStubAssembler::IsCallable(Node* object) { |
| 2915 return IsCallableMap(LoadMap(object)); |
| 2916 } |
| 2917 |
2914 Node* CodeStubAssembler::IsConstructorMap(Node* map) { | 2918 Node* CodeStubAssembler::IsConstructorMap(Node* map) { |
2915 CSA_ASSERT(this, IsMap(map)); | 2919 CSA_ASSERT(this, IsMap(map)); |
2916 return Word32NotEqual( | 2920 return Word32NotEqual( |
2917 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsConstructor)), | 2921 Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsConstructor)), |
2918 Int32Constant(0)); | 2922 Int32Constant(0)); |
2919 } | 2923 } |
2920 | 2924 |
2921 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | 2925 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
2922 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 2926 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
2923 return Int32LessThanOrEqual(instance_type, | 2927 return Int32LessThanOrEqual(instance_type, |
(...skipping 5031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7955 prototype, active_function)); | 7959 prototype, active_function)); |
7956 Goto(&out); | 7960 Goto(&out); |
7957 } | 7961 } |
7958 | 7962 |
7959 Bind(&out); | 7963 Bind(&out); |
7960 return result.value(); | 7964 return result.value(); |
7961 } | 7965 } |
7962 | 7966 |
7963 Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, | 7967 Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, |
7964 Node* context) { | 7968 Node* context) { |
7965 Label return_runtime(this, Label::kDeferred), end(this); | 7969 Variable var_result(this, MachineRepresentation::kTagged); |
7966 Variable result(this, MachineRepresentation::kTagged); | 7970 Label if_notcallable(this, Label::kDeferred), |
| 7971 if_notreceiver(this, Label::kDeferred), if_otherhandler(this), |
| 7972 if_nohandler(this, Label::kDeferred), return_true(this), |
| 7973 return_false(this), return_result(this, &var_result); |
7967 | 7974 |
7968 // Check if no one installed @@hasInstance somewhere. | 7975 // Ensure that the {callable} is actually a JSReceiver. |
7969 GotoUnless( | 7976 GotoIf(TaggedIsSmi(callable), &if_notreceiver); |
7970 WordEqual(LoadObjectField(LoadRoot(Heap::kHasInstanceProtectorRootIndex), | 7977 GotoUnless(IsJSReceiver(callable), &if_notreceiver); |
7971 PropertyCell::kValueOffset), | |
7972 SmiConstant(Smi::FromInt(Isolate::kProtectorValid))), | |
7973 &return_runtime); | |
7974 | 7978 |
7975 // Check if {callable} is a valid receiver. | 7979 // Load the @@hasInstance property from {callable}. |
7976 GotoIf(TaggedIsSmi(callable), &return_runtime); | 7980 Node* inst_of_handler = CallStub(CodeFactory::GetProperty(isolate()), context, |
7977 GotoUnless(IsCallableMap(LoadMap(callable)), &return_runtime); | 7981 callable, HasInstanceSymbolConstant()); |
7978 | 7982 |
7979 // Use the inline OrdinaryHasInstance directly. | 7983 // Optimize for the likely case where {inst_of_handler} is the builtin |
7980 result.Bind(OrdinaryHasInstance(context, callable, object)); | 7984 // Function.prototype[@@hasInstance] method, and emit a direct call in |
7981 Goto(&end); | 7985 // that case without any additional checking. |
7982 | 7986 Node* native_context = LoadNativeContext(context); |
7983 // TODO(bmeurer): Use GetPropertyStub here once available. | 7987 Node* function_has_instance = |
7984 Bind(&return_runtime); | 7988 LoadContextElement(native_context, Context::FUNCTION_HAS_INSTANCE_INDEX); |
| 7989 GotoUnless(WordEqual(inst_of_handler, function_has_instance), |
| 7990 &if_otherhandler); |
7985 { | 7991 { |
7986 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7992 // Call to Function.prototype[@@hasInstance] directly. |
7987 Goto(&end); | 7993 Callable builtin(isolate()->builtins()->FunctionPrototypeHasInstance(), |
| 7994 CallTrampolineDescriptor(isolate())); |
| 7995 Node* result = CallJS(builtin, context, inst_of_handler, callable, object); |
| 7996 var_result.Bind(result); |
| 7997 Goto(&return_result); |
7988 } | 7998 } |
7989 | 7999 |
7990 Bind(&end); | 8000 Bind(&if_otherhandler); |
7991 return result.value(); | 8001 { |
| 8002 // Check if there's actually an {inst_of_handler}. |
| 8003 GotoIf(IsNull(inst_of_handler), &if_nohandler); |
| 8004 GotoIf(IsUndefined(inst_of_handler), &if_nohandler); |
| 8005 |
| 8006 // Call the {inst_of_handler} for {callable} and {object}. |
| 8007 Node* result = CallJS( |
| 8008 CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined), |
| 8009 context, inst_of_handler, callable, object); |
| 8010 |
| 8011 // Convert the {result} to a Boolean. |
| 8012 BranchIfToBooleanIsTrue(result, &return_true, &return_false); |
| 8013 } |
| 8014 |
| 8015 Bind(&if_nohandler); |
| 8016 { |
| 8017 // Ensure that the {callable} is actually Callable. |
| 8018 GotoUnless(IsCallable(callable), &if_notcallable); |
| 8019 |
| 8020 // Use the OrdinaryHasInstance algorithm. |
| 8021 Node* result = CallStub(CodeFactory::OrdinaryHasInstance(isolate()), |
| 8022 context, callable, object); |
| 8023 var_result.Bind(result); |
| 8024 Goto(&return_result); |
| 8025 } |
| 8026 |
| 8027 Bind(&if_notcallable); |
| 8028 { |
| 8029 Node* result = |
| 8030 CallRuntime(Runtime::kThrowNonCallableInInstanceOfCheck, context); |
| 8031 var_result.Bind(result); |
| 8032 Goto(&return_result); |
| 8033 } |
| 8034 |
| 8035 Bind(&if_notreceiver); |
| 8036 { |
| 8037 Node* result = |
| 8038 CallRuntime(Runtime::kThrowNonObjectInInstanceOfCheck, context); |
| 8039 var_result.Bind(result); |
| 8040 Goto(&return_result); |
| 8041 } |
| 8042 |
| 8043 Bind(&return_true); |
| 8044 var_result.Bind(TrueConstant()); |
| 8045 Goto(&return_result); |
| 8046 |
| 8047 Bind(&return_false); |
| 8048 var_result.Bind(FalseConstant()); |
| 8049 Goto(&return_result); |
| 8050 |
| 8051 Bind(&return_result); |
| 8052 return var_result.value(); |
7992 } | 8053 } |
7993 | 8054 |
7994 Node* CodeStubAssembler::NumberInc(Node* value) { | 8055 Node* CodeStubAssembler::NumberInc(Node* value) { |
7995 Variable var_result(this, MachineRepresentation::kTagged), | 8056 Variable var_result(this, MachineRepresentation::kTagged), |
7996 var_finc_value(this, MachineRepresentation::kFloat64); | 8057 var_finc_value(this, MachineRepresentation::kFloat64); |
7997 Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this); | 8058 Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this); |
7998 Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi); | 8059 Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi); |
7999 | 8060 |
8000 Bind(&if_issmi); | 8061 Bind(&if_issmi); |
8001 { | 8062 { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8448 formatted.c_str(), TENURED); | 8509 formatted.c_str(), TENURED); |
8449 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 8510 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
8450 HeapConstant(string)); | 8511 HeapConstant(string)); |
8451 } | 8512 } |
8452 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 8513 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
8453 #endif | 8514 #endif |
8454 } | 8515 } |
8455 | 8516 |
8456 } // namespace internal | 8517 } // namespace internal |
8457 } // namespace v8 | 8518 } // namespace v8 |
OLD | NEW |