| 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 |