| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
| 6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 469 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
| 470 | 470 |
| 471 ExpressionT ParsePrimaryExpression(bool* ok); | 471 ExpressionT ParsePrimaryExpression(bool* ok); |
| 472 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 472 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 473 ExpressionT ParseArrayLiteral(bool* ok); | 473 ExpressionT ParseArrayLiteral(bool* ok); |
| 474 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, | 474 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, |
| 475 bool* ok); | 475 bool* ok); |
| 476 ExpressionT ParseObjectLiteral(bool* ok); | 476 ExpressionT ParseObjectLiteral(bool* ok); |
| 477 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, | 477 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, |
| 478 bool in_class, bool is_static, | 478 bool in_class, bool is_static, |
| 479 bool* has_seen_constructor, |
| 479 bool* ok); | 480 bool* ok); |
| 480 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 481 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
| 481 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 482 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 482 ExpressionT ParseYieldExpression(bool* ok); | 483 ExpressionT ParseYieldExpression(bool* ok); |
| 483 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 484 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 484 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 485 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 485 ExpressionT ParseUnaryExpression(bool* ok); | 486 ExpressionT ParseUnaryExpression(bool* ok); |
| 486 ExpressionT ParsePostfixExpression(bool* ok); | 487 ExpressionT ParsePostfixExpression(bool* ok); |
| 487 ExpressionT ParseLeftHandSideExpression(bool* ok); | 488 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 488 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 489 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 | 1177 |
| 1177 static bool IsBoilerplateProperty(PreParserExpression property) { | 1178 static bool IsBoilerplateProperty(PreParserExpression property) { |
| 1178 // PreParser doesn't count boilerplate properties. | 1179 // PreParser doesn't count boilerplate properties. |
| 1179 return false; | 1180 return false; |
| 1180 } | 1181 } |
| 1181 | 1182 |
| 1182 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1183 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
| 1183 return false; | 1184 return false; |
| 1184 } | 1185 } |
| 1185 | 1186 |
| 1186 bool IsConstructorProperty(PreParserExpression property) { return false; } | |
| 1187 | |
| 1188 static PreParserExpression GetPropertyValue(PreParserExpression property) { | 1187 static PreParserExpression GetPropertyValue(PreParserExpression property) { |
| 1189 UNREACHABLE(); | |
| 1190 return PreParserExpression::Default(); | 1188 return PreParserExpression::Default(); |
| 1191 } | 1189 } |
| 1192 | 1190 |
| 1193 // Functions for encapsulating the differences between parsing and preparsing; | 1191 // Functions for encapsulating the differences between parsing and preparsing; |
| 1194 // operations interleaved with the recursive descent. | 1192 // operations interleaved with the recursive descent. |
| 1195 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1193 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
| 1196 // PreParser should not use FuncNameInferrer. | 1194 // PreParser should not use FuncNameInferrer. |
| 1197 UNREACHABLE(); | 1195 UNREACHABLE(); |
| 1198 } | 1196 } |
| 1199 static void PushPropertyName(FuncNameInferrer* fni, | 1197 static void PushPropertyName(FuncNameInferrer* fni, |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); | 1916 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); |
| 1919 } | 1917 } |
| 1920 UNREACHABLE(); | 1918 UNREACHABLE(); |
| 1921 return this->EmptyIdentifier(); | 1919 return this->EmptyIdentifier(); |
| 1922 } | 1920 } |
| 1923 | 1921 |
| 1924 | 1922 |
| 1925 template <class Traits> | 1923 template <class Traits> |
| 1926 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< | 1924 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
| 1927 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, | 1925 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, |
| 1928 bool in_class, bool is_static, bool* ok) { | 1926 bool in_class, bool is_static, |
| 1927 bool* has_seen_constructor, bool* ok) { |
| 1928 DCHECK(!in_class || is_static || has_seen_constructor != NULL); |
| 1929 ExpressionT value = this->EmptyExpression(); | 1929 ExpressionT value = this->EmptyExpression(); |
| 1930 bool is_get = false; | 1930 bool is_get = false; |
| 1931 bool is_set = false; | 1931 bool is_set = false; |
| 1932 bool name_is_static = false; | 1932 bool name_is_static = false; |
| 1933 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 1933 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
| 1934 | 1934 |
| 1935 Token::Value name_token = peek(); | 1935 Token::Value name_token = peek(); |
| 1936 int next_pos = peek_position(); | 1936 int next_pos = peek_position(); |
| 1937 IdentifierT name = | 1937 IdentifierT name = |
| 1938 ParsePropertyName(&is_get, &is_set, &name_is_static, | 1938 ParsePropertyName(&is_get, &is_set, &name_is_static, |
| 1939 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1939 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1940 | 1940 |
| 1941 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 1941 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
| 1942 | 1942 |
| 1943 if (!in_class && !is_generator && peek() == Token::COLON) { | 1943 if (!in_class && !is_generator && peek() == Token::COLON) { |
| 1944 // PropertyDefinition : PropertyName ':' AssignmentExpression | 1944 // PropertyDefinition : PropertyName ':' AssignmentExpression |
| 1945 checker->CheckProperty(name_token, kValueProperty, | 1945 if (checker != NULL) { |
| 1946 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1946 checker->CheckProperty(name_token, kValueProperty, |
| 1947 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1948 } |
| 1947 Consume(Token::COLON); | 1949 Consume(Token::COLON); |
| 1948 value = this->ParseAssignmentExpression( | 1950 value = this->ParseAssignmentExpression( |
| 1949 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1951 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1950 | 1952 |
| 1951 } else if (is_generator || | 1953 } else if (is_generator || |
| 1952 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 1954 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
| 1953 // Concise Method | 1955 // Concise Method |
| 1954 | 1956 |
| 1955 if (is_static && this->IsPrototype(name)) { | 1957 if (is_static && this->IsPrototype(name)) { |
| 1956 ReportMessageAt(scanner()->location(), "static_prototype"); | 1958 ReportMessageAt(scanner()->location(), "static_prototype"); |
| 1957 *ok = false; | 1959 *ok = false; |
| 1958 return this->EmptyObjectLiteralProperty(); | 1960 return this->EmptyObjectLiteralProperty(); |
| 1959 } | 1961 } |
| 1960 | 1962 |
| 1961 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1963 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
| 1962 : FunctionKind::kConciseMethod; | 1964 : FunctionKind::kConciseMethod; |
| 1963 | 1965 |
| 1964 if (in_class && !is_static && this->IsConstructor(name)) { | 1966 if (in_class && !is_static && this->IsConstructor(name)) { |
| 1965 if (is_generator) { | 1967 if (is_generator) { |
| 1966 ReportMessageAt(scanner()->location(), "constructor_special_method"); | 1968 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
| 1967 *ok = false; | 1969 *ok = false; |
| 1968 return this->EmptyObjectLiteralProperty(); | 1970 return this->EmptyObjectLiteralProperty(); |
| 1969 } | 1971 } |
| 1970 | 1972 |
| 1973 if (*has_seen_constructor) { |
| 1974 ReportMessageAt(scanner()->location(), "duplicate_constructor"); |
| 1975 *ok = false; |
| 1976 return this->EmptyObjectLiteralProperty(); |
| 1977 } |
| 1978 |
| 1979 *has_seen_constructor = true; |
| 1971 kind = FunctionKind::kNormalFunction; | 1980 kind = FunctionKind::kNormalFunction; |
| 1972 } | 1981 } |
| 1973 | 1982 |
| 1974 checker->CheckProperty(name_token, kValueProperty, | 1983 if (checker != NULL) { |
| 1975 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1984 checker->CheckProperty(name_token, kValueProperty, |
| 1985 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1986 } |
| 1976 | 1987 |
| 1977 value = this->ParseFunctionLiteral( | 1988 value = this->ParseFunctionLiteral( |
| 1978 name, scanner()->location(), | 1989 name, scanner()->location(), |
| 1979 false, // reserved words are allowed here | 1990 false, // reserved words are allowed here |
| 1980 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 1991 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 1981 FunctionLiteral::NORMAL_ARITY, | 1992 FunctionLiteral::NORMAL_ARITY, |
| 1982 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1993 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1983 | 1994 |
| 1984 } else if (in_class && name_is_static && !is_static) { | 1995 } else if (in_class && name_is_static && !is_static) { |
| 1985 // static MethodDefinition | 1996 // static MethodDefinition |
| 1986 return ParsePropertyDefinition(checker, true, true, ok); | 1997 return ParsePropertyDefinition(checker, true, true, NULL, ok); |
| 1987 | 1998 |
| 1988 } else if (is_get || is_set) { | 1999 } else if (is_get || is_set) { |
| 1989 // Accessor | 2000 // Accessor |
| 1990 bool dont_care = false; | 2001 bool dont_care = false; |
| 1991 name_token = peek(); | 2002 name_token = peek(); |
| 1992 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, | 2003 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, |
| 1993 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2004 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1994 | 2005 |
| 1995 // Validate the property. | 2006 // Validate the property. |
| 1996 if (is_static && this->IsPrototype(name)) { | 2007 if (is_static && this->IsPrototype(name)) { |
| 1997 ReportMessageAt(scanner()->location(), "static_prototype"); | 2008 ReportMessageAt(scanner()->location(), "static_prototype"); |
| 1998 *ok = false; | 2009 *ok = false; |
| 1999 return this->EmptyObjectLiteralProperty(); | 2010 return this->EmptyObjectLiteralProperty(); |
| 2000 } else if (in_class && !is_static && this->IsConstructor(name)) { | 2011 } else if (in_class && !is_static && this->IsConstructor(name)) { |
| 2001 // ES6, spec draft rev 27, treats static get constructor as an error too. | |
| 2002 // https://bugs.ecmascript.org/show_bug.cgi?id=3223 | |
| 2003 // TODO(arv): Update when bug is resolved. | |
| 2004 ReportMessageAt(scanner()->location(), "constructor_special_method"); | 2012 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
| 2005 *ok = false; | 2013 *ok = false; |
| 2006 return this->EmptyObjectLiteralProperty(); | 2014 return this->EmptyObjectLiteralProperty(); |
| 2007 } | 2015 } |
| 2008 checker->CheckProperty(name_token, | 2016 if (checker != NULL) { |
| 2009 is_get ? kGetterProperty : kSetterProperty, | 2017 checker->CheckProperty(name_token, |
| 2010 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2018 is_get ? kGetterProperty : kSetterProperty, |
| 2019 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2020 } |
| 2011 | 2021 |
| 2012 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2022 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
| 2013 name, scanner()->location(), | 2023 name, scanner()->location(), |
| 2014 false, // reserved words are allowed here | 2024 false, // reserved words are allowed here |
| 2015 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, | 2025 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, |
| 2016 FunctionLiteral::ANONYMOUS_EXPRESSION, | 2026 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 2017 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2027 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
| 2018 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2028 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2019 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, | 2029 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, |
| 2020 is_static); | 2030 is_static); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2054 | 2064 |
| 2055 ObjectLiteralChecker checker(this, strict_mode()); | 2065 ObjectLiteralChecker checker(this, strict_mode()); |
| 2056 | 2066 |
| 2057 Expect(Token::LBRACE, CHECK_OK); | 2067 Expect(Token::LBRACE, CHECK_OK); |
| 2058 | 2068 |
| 2059 while (peek() != Token::RBRACE) { | 2069 while (peek() != Token::RBRACE) { |
| 2060 if (fni_ != NULL) fni_->Enter(); | 2070 if (fni_ != NULL) fni_->Enter(); |
| 2061 | 2071 |
| 2062 const bool in_class = false; | 2072 const bool in_class = false; |
| 2063 const bool is_static = false; | 2073 const bool is_static = false; |
| 2064 ObjectLiteralPropertyT property = | 2074 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| 2065 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); | 2075 &checker, in_class, is_static, NULL, CHECK_OK); |
| 2066 | 2076 |
| 2067 // Mark top-level object literals that contain function literals and | 2077 // Mark top-level object literals that contain function literals and |
| 2068 // pretenure the literal so it can be added as a constant function | 2078 // pretenure the literal so it can be added as a constant function |
| 2069 // property. (Parser only.) | 2079 // property. (Parser only.) |
| 2070 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2080 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
| 2071 &has_function); | 2081 &has_function); |
| 2072 | 2082 |
| 2073 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2083 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 2074 if (this->IsBoilerplateProperty(property)) { | 2084 if (this->IsBoilerplateProperty(property)) { |
| 2075 number_of_boilerplate_properties++; | 2085 number_of_boilerplate_properties++; |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2737 scope_->SetStrictMode(STRICT); | 2747 scope_->SetStrictMode(STRICT); |
| 2738 extends = this->ParseLeftHandSideExpression(CHECK_OK); | 2748 extends = this->ParseLeftHandSideExpression(CHECK_OK); |
| 2739 } | 2749 } |
| 2740 | 2750 |
| 2741 // TODO(arv): Implement scopes and name binding in class body only. | 2751 // TODO(arv): Implement scopes and name binding in class body only. |
| 2742 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); | 2752 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); |
| 2743 BlockState block_state(&scope_, Traits::Type::ptr_to_scope(scope)); | 2753 BlockState block_state(&scope_, Traits::Type::ptr_to_scope(scope)); |
| 2744 scope_->SetStrictMode(STRICT); | 2754 scope_->SetStrictMode(STRICT); |
| 2745 scope_->SetScopeName(name); | 2755 scope_->SetScopeName(name); |
| 2746 | 2756 |
| 2747 ObjectLiteralChecker checker(this, STRICT); | |
| 2748 typename Traits::Type::PropertyList properties = | 2757 typename Traits::Type::PropertyList properties = |
| 2749 this->NewPropertyList(4, zone_); | 2758 this->NewPropertyList(4, zone_); |
| 2750 ExpressionT constructor = this->EmptyExpression(); | 2759 ExpressionT constructor = this->EmptyExpression(); |
| 2760 bool has_seen_constructor = false; |
| 2751 | 2761 |
| 2752 Expect(Token::LBRACE, CHECK_OK); | 2762 Expect(Token::LBRACE, CHECK_OK); |
| 2753 while (peek() != Token::RBRACE) { | 2763 while (peek() != Token::RBRACE) { |
| 2754 if (Check(Token::SEMICOLON)) continue; | 2764 if (Check(Token::SEMICOLON)) continue; |
| 2755 if (fni_ != NULL) fni_->Enter(); | 2765 if (fni_ != NULL) fni_->Enter(); |
| 2756 | |
| 2757 const bool in_class = true; | 2766 const bool in_class = true; |
| 2758 const bool is_static = false; | 2767 const bool is_static = false; |
| 2759 ObjectLiteralPropertyT property = | 2768 bool old_has_seen_constructor = has_seen_constructor; |
| 2760 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); | 2769 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| 2770 NULL, in_class, is_static, &has_seen_constructor, CHECK_OK); |
| 2761 | 2771 |
| 2762 if (this->IsConstructorProperty(property)) { | 2772 if (has_seen_constructor != old_has_seen_constructor) { |
| 2763 constructor = this->GetPropertyValue(property); | 2773 constructor = this->GetPropertyValue(property); |
| 2764 } else { | 2774 } else { |
| 2765 properties->Add(property, zone()); | 2775 properties->Add(property, zone()); |
| 2766 } | 2776 } |
| 2767 | 2777 |
| 2768 if (fni_ != NULL) { | 2778 if (fni_ != NULL) { |
| 2769 fni_->Infer(); | 2779 fni_->Infer(); |
| 2770 fni_->Leave(); | 2780 fni_->Leave(); |
| 2771 } | 2781 } |
| 2772 } | 2782 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2831 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2841 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
| 2832 // Both accessors of the same type. | 2842 // Both accessors of the same type. |
| 2833 parser()->ReportMessage("accessor_get_set"); | 2843 parser()->ReportMessage("accessor_get_set"); |
| 2834 } | 2844 } |
| 2835 *ok = false; | 2845 *ok = false; |
| 2836 } | 2846 } |
| 2837 } | 2847 } |
| 2838 } } // v8::internal | 2848 } } // v8::internal |
| 2839 | 2849 |
| 2840 #endif // V8_PREPARSER_H | 2850 #endif // V8_PREPARSER_H |
| OLD | NEW |