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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1611 // Statement: | 1611 // Statement: |
1612 // GeneratorDeclaration | 1612 // GeneratorDeclaration |
1613 if (strict_mode() == STRICT) { | 1613 if (strict_mode() == STRICT) { |
1614 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1614 ReportMessageAt(scanner()->peek_location(), "strict_function"); |
1615 *ok = false; | 1615 *ok = false; |
1616 return NULL; | 1616 return NULL; |
1617 } | 1617 } |
1618 return ParseFunctionDeclaration(NULL, ok); | 1618 return ParseFunctionDeclaration(NULL, ok); |
1619 } | 1619 } |
1620 | 1620 |
1621 case Token::CLASS: | |
1622 return ParseClassDeclaration(NULL, ok); | |
1623 | |
1624 case Token::DEBUGGER: | 1621 case Token::DEBUGGER: |
1625 return ParseDebuggerStatement(ok); | 1622 return ParseDebuggerStatement(ok); |
1626 | 1623 |
1627 case Token::VAR: | 1624 case Token::VAR: |
1628 case Token::CONST: | |
1629 return ParseVariableStatement(kStatement, NULL, ok); | 1625 return ParseVariableStatement(kStatement, NULL, ok); |
1630 | 1626 |
1631 case Token::LET: | 1627 case Token::CONST: |
1632 DCHECK(allow_harmony_scoping()); | 1628 // In ES6 CONST is not allowed as a Statement, only as a |
1633 if (strict_mode() == STRICT) { | 1629 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
| 1630 // backwards compatibility. |
| 1631 if (strict_mode() == SLOPPY) { |
1634 return ParseVariableStatement(kStatement, NULL, ok); | 1632 return ParseVariableStatement(kStatement, NULL, ok); |
1635 } | 1633 } |
1636 // Fall through. | 1634 |
| 1635 // Fall through. |
1637 default: | 1636 default: |
1638 return ParseExpressionOrLabelledStatement(labels, ok); | 1637 return ParseExpressionOrLabelledStatement(labels, ok); |
1639 } | 1638 } |
1640 } | 1639 } |
1641 | 1640 |
1642 | 1641 |
1643 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1642 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1644 VariableMode mode, Interface* interface) { | 1643 VariableMode mode, Interface* interface) { |
1645 // If we are inside a function, a declaration of a var/const variable is a | 1644 // If we are inside a function, a declaration of a var/const variable is a |
1646 // truly local variable, and the scope of the variable is always the function | 1645 // truly local variable, and the scope of the variable is always the function |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 // True if the binding needs initialization. 'let' and 'const' declared | 2031 // True if the binding needs initialization. 'let' and 'const' declared |
2033 // bindings are created uninitialized by their declaration nodes and | 2032 // bindings are created uninitialized by their declaration nodes and |
2034 // need initialization. 'var' declared bindings are always initialized | 2033 // need initialization. 'var' declared bindings are always initialized |
2035 // immediately by their declaration nodes. | 2034 // immediately by their declaration nodes. |
2036 bool needs_init = false; | 2035 bool needs_init = false; |
2037 bool is_const = false; | 2036 bool is_const = false; |
2038 Token::Value init_op = Token::INIT_VAR; | 2037 Token::Value init_op = Token::INIT_VAR; |
2039 if (peek() == Token::VAR) { | 2038 if (peek() == Token::VAR) { |
2040 Consume(Token::VAR); | 2039 Consume(Token::VAR); |
2041 } else if (peek() == Token::CONST) { | 2040 } else if (peek() == Token::CONST) { |
2042 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: | |
2043 // | |
2044 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | |
2045 // | |
2046 // * It is a Syntax Error if the code that matches this production is not | |
2047 // contained in extended code. | |
2048 // | |
2049 // However disallowing const in sloppy mode will break compatibility with | |
2050 // existing pages. Therefore we keep allowing const with the old | |
2051 // non-harmony semantics in sloppy mode. | |
2052 Consume(Token::CONST); | 2041 Consume(Token::CONST); |
2053 switch (strict_mode()) { | 2042 switch (strict_mode()) { |
2054 case SLOPPY: | 2043 case SLOPPY: |
2055 mode = CONST_LEGACY; | 2044 mode = CONST_LEGACY; |
2056 init_op = Token::INIT_CONST_LEGACY; | 2045 init_op = Token::INIT_CONST_LEGACY; |
2057 break; | 2046 break; |
2058 case STRICT: | 2047 case STRICT: |
2059 if (allow_harmony_scoping()) { | 2048 DCHECK(var_context != kStatement); |
2060 if (var_context == kStatement) { | 2049 // In ES5 const is not allowed in strict mode. |
2061 // In strict mode 'const' declarations are only allowed in source | 2050 if (!allow_harmony_scoping()) { |
2062 // element positions. | |
2063 ReportMessage("unprotected_const"); | |
2064 *ok = false; | |
2065 return NULL; | |
2066 } | |
2067 mode = CONST; | |
2068 init_op = Token::INIT_CONST; | |
2069 } else { | |
2070 ReportMessage("strict_const"); | 2051 ReportMessage("strict_const"); |
2071 *ok = false; | 2052 *ok = false; |
2072 return NULL; | 2053 return NULL; |
2073 } | 2054 } |
| 2055 mode = CONST; |
| 2056 init_op = Token::INIT_CONST; |
2074 } | 2057 } |
2075 is_const = true; | 2058 is_const = true; |
2076 needs_init = true; | 2059 needs_init = true; |
2077 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 2060 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
2078 DCHECK(allow_harmony_scoping()); | 2061 DCHECK(allow_harmony_scoping()); |
2079 Consume(Token::LET); | 2062 Consume(Token::LET); |
2080 if (var_context == kStatement) { | 2063 DCHECK(var_context != kStatement); |
2081 // Let declarations are only allowed in source element positions. | |
2082 ReportMessage("unprotected_let"); | |
2083 *ok = false; | |
2084 return NULL; | |
2085 } | |
2086 mode = LET; | 2064 mode = LET; |
2087 needs_init = true; | 2065 needs_init = true; |
2088 init_op = Token::INIT_LET; | 2066 init_op = Token::INIT_LET; |
2089 } else { | 2067 } else { |
2090 UNREACHABLE(); // by current callers | 2068 UNREACHABLE(); // by current callers |
2091 } | 2069 } |
2092 | 2070 |
2093 Scope* declaration_scope = DeclarationScope(mode); | 2071 Scope* declaration_scope = DeclarationScope(mode); |
2094 | 2072 |
2095 // The scope of a var/const declared variable anywhere inside a function | 2073 // The scope of a var/const declared variable anywhere inside a function |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 } | 2316 } |
2339 return false; | 2317 return false; |
2340 } | 2318 } |
2341 | 2319 |
2342 | 2320 |
2343 Statement* Parser::ParseExpressionOrLabelledStatement( | 2321 Statement* Parser::ParseExpressionOrLabelledStatement( |
2344 ZoneList<const AstRawString*>* labels, bool* ok) { | 2322 ZoneList<const AstRawString*>* labels, bool* ok) { |
2345 // ExpressionStatement | LabelledStatement :: | 2323 // ExpressionStatement | LabelledStatement :: |
2346 // Expression ';' | 2324 // Expression ';' |
2347 // Identifier ':' Statement | 2325 // Identifier ':' Statement |
| 2326 // |
| 2327 // ExpressionStatement[Yield] : |
| 2328 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ; |
| 2329 |
| 2330 switch (peek()) { |
| 2331 case Token::FUNCTION: |
| 2332 case Token::LBRACE: |
| 2333 UNREACHABLE(); // Always handled by the callers. |
| 2334 case Token::CLASS: |
| 2335 ReportUnexpectedToken(Next()); |
| 2336 *ok = false; |
| 2337 return nullptr; |
| 2338 |
| 2339 // TODO(arv): Handle `let [` |
| 2340 // https://code.google.com/p/v8/issues/detail?id=3847 |
| 2341 |
| 2342 default: |
| 2343 break; |
| 2344 } |
| 2345 |
2348 int pos = peek_position(); | 2346 int pos = peek_position(); |
2349 bool starts_with_idenfifier = peek_any_identifier(); | 2347 bool starts_with_idenfifier = peek_any_identifier(); |
2350 Expression* expr = ParseExpression(true, CHECK_OK); | 2348 Expression* expr = ParseExpression(true, CHECK_OK); |
2351 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2349 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
2352 expr->AsVariableProxy() != NULL && | 2350 expr->AsVariableProxy() != NULL && |
2353 !expr->AsVariableProxy()->is_this()) { | 2351 !expr->AsVariableProxy()->is_this()) { |
2354 // Expression is a single identifier, and not, e.g., a parenthesized | 2352 // Expression is a single identifier, and not, e.g., a parenthesized |
2355 // identifier. | 2353 // identifier. |
2356 VariableProxy* var = expr->AsVariableProxy(); | 2354 VariableProxy* var = expr->AsVariableProxy(); |
2357 const AstRawString* label = var->raw_name(); | 2355 const AstRawString* label = var->raw_name(); |
(...skipping 2892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5250 } else { | 5248 } else { |
5251 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5249 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5252 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5250 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5253 raw_string->length()); | 5251 raw_string->length()); |
5254 } | 5252 } |
5255 } | 5253 } |
5256 | 5254 |
5257 return running_hash; | 5255 return running_hash; |
5258 } | 5256 } |
5259 } } // namespace v8::internal | 5257 } } // namespace v8::internal |
OLD | NEW |