OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 10885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10896 } | 10896 } |
10897 | 10897 |
10898 if (!maybe_string_add && !is_strong(strength)) { | 10898 if (!maybe_string_add && !is_strong(strength)) { |
10899 left = TruncateToNumber(left, &left_type); | 10899 left = TruncateToNumber(left, &left_type); |
10900 right = TruncateToNumber(right, &right_type); | 10900 right = TruncateToNumber(right, &right_type); |
10901 } | 10901 } |
10902 | 10902 |
10903 // Special case for string addition here. | 10903 // Special case for string addition here. |
10904 if (op == Token::ADD && | 10904 if (op == Token::ADD && |
10905 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 10905 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
10906 // Validate type feedback for left argument. | 10906 if (is_strong(strength)) { |
10907 if (left_type->Is(Type::String())) { | 10907 // In strong mode, if the one side of an addition is a string, |
| 10908 // the other side must be a string too. |
10908 left = BuildCheckString(left); | 10909 left = BuildCheckString(left); |
10909 } | 10910 right = BuildCheckString(right); |
| 10911 } else { |
| 10912 // Validate type feedback for left argument. |
| 10913 if (left_type->Is(Type::String())) { |
| 10914 left = BuildCheckString(left); |
| 10915 } |
10910 | 10916 |
10911 // Validate type feedback for right argument. | 10917 // Validate type feedback for right argument. |
10912 if (right_type->Is(Type::String())) { | 10918 if (right_type->Is(Type::String())) { |
10913 right = BuildCheckString(right); | 10919 right = BuildCheckString(right); |
10914 } | 10920 } |
10915 | 10921 |
10916 // Convert left argument as necessary. | 10922 // Convert left argument as necessary. |
10917 if (left_type->Is(Type::Number()) && !is_strong(strength)) { | 10923 if (left_type->Is(Type::Number())) { |
10918 DCHECK(right_type->Is(Type::String())); | 10924 DCHECK(right_type->Is(Type::String())); |
10919 left = BuildNumberToString(left, left_type); | 10925 left = BuildNumberToString(left, left_type); |
10920 } else if (!left_type->Is(Type::String())) { | 10926 } else if (!left_type->Is(Type::String())) { |
10921 DCHECK(right_type->Is(Type::String())); | 10927 DCHECK(right_type->Is(Type::String())); |
10922 HValue* function = AddLoadJSBuiltin( | 10928 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); |
10923 is_strong(strength) ? Builtins::STRING_ADD_RIGHT_STRONG | 10929 Add<HPushArguments>(left, right); |
10924 : Builtins::STRING_ADD_RIGHT); | 10930 return AddUncasted<HInvokeFunction>(function, 2); |
10925 Add<HPushArguments>(left, right); | 10931 } |
10926 return AddUncasted<HInvokeFunction>(function, 2); | |
10927 } | |
10928 | 10932 |
10929 // Convert right argument as necessary. | 10933 // Convert right argument as necessary. |
10930 if (right_type->Is(Type::Number()) && !is_strong(strength)) { | 10934 if (right_type->Is(Type::Number())) { |
10931 DCHECK(left_type->Is(Type::String())); | 10935 DCHECK(left_type->Is(Type::String())); |
10932 right = BuildNumberToString(right, right_type); | 10936 right = BuildNumberToString(right, right_type); |
10933 } else if (!right_type->Is(Type::String())) { | 10937 } else if (!right_type->Is(Type::String())) { |
10934 DCHECK(left_type->Is(Type::String())); | 10938 DCHECK(left_type->Is(Type::String())); |
10935 HValue* function = AddLoadJSBuiltin(is_strong(strength) | 10939 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
10936 ? Builtins::STRING_ADD_LEFT_STRONG | 10940 Add<HPushArguments>(left, right); |
10937 : Builtins::STRING_ADD_LEFT); | 10941 return AddUncasted<HInvokeFunction>(function, 2); |
10938 Add<HPushArguments>(left, right); | 10942 } |
10939 return AddUncasted<HInvokeFunction>(function, 2); | |
10940 } | 10943 } |
10941 | 10944 |
10942 // Fast paths for empty constant strings. | 10945 // Fast paths for empty constant strings. |
10943 Handle<String> left_string = | 10946 Handle<String> left_string = |
10944 left->IsConstant() && HConstant::cast(left)->HasStringValue() | 10947 left->IsConstant() && HConstant::cast(left)->HasStringValue() |
10945 ? HConstant::cast(left)->StringValue() | 10948 ? HConstant::cast(left)->StringValue() |
10946 : Handle<String>(); | 10949 : Handle<String>(); |
10947 Handle<String> right_string = | 10950 Handle<String> right_string = |
10948 right->IsConstant() && HConstant::cast(right)->HasStringValue() | 10951 right->IsConstant() && HConstant::cast(right)->HasStringValue() |
10949 ? HConstant::cast(right)->StringValue() | 10952 ? HConstant::cast(right)->StringValue() |
(...skipping 2482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13432 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13435 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13433 } | 13436 } |
13434 | 13437 |
13435 #ifdef DEBUG | 13438 #ifdef DEBUG |
13436 graph_->Verify(false); // No full verify. | 13439 graph_->Verify(false); // No full verify. |
13437 #endif | 13440 #endif |
13438 } | 13441 } |
13439 | 13442 |
13440 } // namespace internal | 13443 } // namespace internal |
13441 } // namespace v8 | 13444 } // namespace v8 |
OLD | NEW |