OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/compilation-dependencies.h" | 10 #include "src/compilation-dependencies.h" |
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 } | 1911 } |
1912 } | 1912 } |
1913 | 1913 |
1914 } // namespace | 1914 } // namespace |
1915 | 1915 |
1916 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) | 1916 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) |
1917 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) { | 1917 Reduction JSBuiltinReducer::ReduceStringCharAt(Node* node) { |
1918 // We need at least target, receiver and index parameters. | 1918 // We need at least target, receiver and index parameters. |
1919 if (node->op()->ValueInputCount() >= 3) { | 1919 if (node->op()->ValueInputCount() >= 3) { |
1920 Node* index = NodeProperties::GetValueInput(node, 2); | 1920 Node* index = NodeProperties::GetValueInput(node, 2); |
1921 Type* index_type = NodeProperties::GetType(index); | |
1922 Node* effect = NodeProperties::GetEffectInput(node); | 1921 Node* effect = NodeProperties::GetEffectInput(node); |
1923 Node* control = NodeProperties::GetControlInput(node); | 1922 Node* control = NodeProperties::GetControlInput(node); |
1924 | 1923 |
1925 if (index_type->Is(Type::Integral32OrMinusZeroOrNaN())) { | 1924 if (Node* receiver = GetStringWitness(node)) { |
1926 if (Node* receiver = GetStringWitness(node)) { | 1925 // Determine the {receiver} length. |
1927 if (!index_type->Is(Type::Unsigned32())) { | 1926 Node* length = effect = graph()->NewNode( |
1928 // Map -0 and NaN to 0 (as per ToInteger), and the values in | 1927 simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, |
1929 // the [-2^31,-1] range to the [2^31,2^32-1] range, which will | 1928 effect, control); |
1930 // be considered out-of-bounds as well, because of the maximal | |
1931 // String length limit in V8. | |
1932 STATIC_ASSERT(String::kMaxLength <= kMaxInt); | |
1933 index = graph()->NewNode(simplified()->NumberToUint32(), index); | |
1934 } | |
1935 | 1929 |
1936 // Determine the {receiver} length. | 1930 // Check if {index} is less than {receiver} length. |
1937 Node* receiver_length = effect = graph()->NewNode( | 1931 index = effect = graph()->NewNode(simplified()->CheckBounds(), index, |
1938 simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, | 1932 length, effect, control); |
1939 effect, control); | |
1940 | 1933 |
1941 // Check if {index} is less than {receiver} length. | 1934 // Load the character from the {receiver} as single character string. |
1942 Node* check = graph()->NewNode(simplified()->NumberLessThan(), index, | 1935 Node* value = graph()->NewNode(simplified()->StringCharAt(), receiver, |
1943 receiver_length); | 1936 index, control); |
1944 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 1937 ReplaceWithValue(node, value, effect, control); |
1945 check, control); | 1938 return Replace(value); |
1946 | |
1947 // Return the character from the {receiver} as single character string. | |
1948 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
1949 Node* vtrue = graph()->NewNode(simplified()->StringCharAt(), receiver, | |
1950 index, if_true); | |
1951 | |
1952 // Return the empty string otherwise. | |
1953 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
1954 Node* vfalse = jsgraph()->EmptyStringConstant(); | |
1955 | |
1956 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
1957 Node* value = | |
1958 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
1959 vtrue, vfalse, control); | |
1960 | |
1961 ReplaceWithValue(node, value, effect, control); | |
1962 return Replace(value); | |
1963 } | |
1964 } | 1939 } |
1965 } | 1940 } |
1966 | 1941 |
1967 return NoChange(); | 1942 return NoChange(); |
1968 } | 1943 } |
1969 | 1944 |
1970 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) | 1945 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) |
1971 Reduction JSBuiltinReducer::ReduceStringCharCodeAt(Node* node) { | 1946 Reduction JSBuiltinReducer::ReduceStringCharCodeAt(Node* node) { |
1972 // We need at least target, receiver and index parameters. | 1947 // We need at least target, receiver and index parameters. |
1973 if (node->op()->ValueInputCount() >= 3) { | 1948 if (node->op()->ValueInputCount() >= 3) { |
1974 Node* index = NodeProperties::GetValueInput(node, 2); | 1949 Node* index = NodeProperties::GetValueInput(node, 2); |
1975 Type* index_type = NodeProperties::GetType(index); | |
1976 Node* effect = NodeProperties::GetEffectInput(node); | 1950 Node* effect = NodeProperties::GetEffectInput(node); |
1977 Node* control = NodeProperties::GetControlInput(node); | 1951 Node* control = NodeProperties::GetControlInput(node); |
1978 | 1952 |
1979 if (index_type->Is(Type::Integral32OrMinusZeroOrNaN())) { | 1953 if (Node* receiver = GetStringWitness(node)) { |
1980 if (Node* receiver = GetStringWitness(node)) { | 1954 // Determine the {receiver} length. |
1981 if (!index_type->Is(Type::Unsigned32())) { | 1955 Node* length = effect = graph()->NewNode( |
1982 // Map -0 and NaN to 0 (as per ToInteger), and the values in | 1956 simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, |
1983 // the [-2^31,-1] range to the [2^31,2^32-1] range, which will | 1957 effect, control); |
1984 // be considered out-of-bounds as well, because of the maximal | |
1985 // String length limit in V8. | |
1986 STATIC_ASSERT(String::kMaxLength <= kMaxInt); | |
1987 index = graph()->NewNode(simplified()->NumberToUint32(), index); | |
1988 } | |
1989 | 1958 |
1990 // Determine the {receiver} length. | 1959 // Check if {index} is less than {receiver} length. |
1991 Node* receiver_length = effect = graph()->NewNode( | 1960 index = effect = graph()->NewNode(simplified()->CheckBounds(), index, |
1992 simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, | 1961 length, effect, control); |
1993 effect, control); | |
1994 | 1962 |
1995 // Check if {index} is less than {receiver} length. | 1963 // Load the character from the {receiver}. |
1996 Node* check = graph()->NewNode(simplified()->NumberLessThan(), index, | 1964 Node* value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, |
1997 receiver_length); | 1965 index, control); |
1998 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 1966 ReplaceWithValue(node, value, effect, control); |
1999 check, control); | 1967 return Replace(value); |
2000 | |
2001 // Load the character from the {receiver}. | |
2002 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
2003 Node* vtrue = graph()->NewNode(simplified()->StringCharCodeAt(), | |
2004 receiver, index, if_true); | |
2005 | |
2006 // Return NaN otherwise. | |
2007 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
2008 Node* vfalse = jsgraph()->NaNConstant(); | |
2009 | |
2010 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
2011 Node* value = | |
2012 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
2013 vtrue, vfalse, control); | |
2014 | |
2015 ReplaceWithValue(node, value, effect, control); | |
2016 return Replace(value); | |
2017 } | |
2018 } | 1968 } |
2019 } | 1969 } |
2020 | 1970 |
2021 return NoChange(); | 1971 return NoChange(); |
2022 } | 1972 } |
2023 | 1973 |
2024 // ES6 String.prototype.concat(...args) | 1974 // ES6 String.prototype.concat(...args) |
2025 // #sec-string.prototype.concat | 1975 // #sec-string.prototype.concat |
2026 Reduction JSBuiltinReducer::ReduceStringConcat(Node* node) { | 1976 Reduction JSBuiltinReducer::ReduceStringConcat(Node* node) { |
2027 if (Node* receiver = GetStringWitness(node)) { | 1977 if (Node* receiver = GetStringWitness(node)) { |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2527 return jsgraph()->simplified(); | 2477 return jsgraph()->simplified(); |
2528 } | 2478 } |
2529 | 2479 |
2530 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2480 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
2531 return jsgraph()->javascript(); | 2481 return jsgraph()->javascript(); |
2532 } | 2482 } |
2533 | 2483 |
2534 } // namespace compiler | 2484 } // namespace compiler |
2535 } // namespace internal | 2485 } // namespace internal |
2536 } // namespace v8 | 2486 } // namespace v8 |
OLD | NEW |