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