OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 | 155 |
156 | 156 |
157 #define CHECK_OK ok); \ | 157 #define CHECK_OK ok); \ |
158 if (!*ok) return kUnknownSourceElements; \ | 158 if (!*ok) return kUnknownSourceElements; \ |
159 ((void)0 | 159 ((void)0 |
160 #define DUMMY ) // to make indentation work | 160 #define DUMMY ) // to make indentation work |
161 #undef DUMMY | 161 #undef DUMMY |
162 | 162 |
163 | 163 |
164 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { | 164 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { |
165 // (Ecma 262 5th Edition, clause 14): | 165 // ECMA 262 6th Edition |
166 // SourceElement: | 166 // StatementListItem[Yield, Return] : |
167 // Statement | 167 // Statement[?Yield, ?Return] |
168 // FunctionDeclaration | 168 // Declaration[?Yield] |
169 // | 169 // |
170 // In harmony mode we allow additionally the following productions | 170 // Declaration[Yield] : |
171 // SourceElement: | 171 // HoistableDeclaration[?Yield] |
172 // LetDeclaration | 172 // ClassDeclaration[?Yield] |
173 // ConstDeclaration | 173 // LexicalDeclaration[In, ?Yield] |
174 // GeneratorDeclaration | 174 // |
175 // HoistableDeclaration[Yield, Default] : | |
176 // FunctionDeclaration[?Yield, ?Default] | |
177 // GeneratorDeclaration[?Yield, ?Default] | |
178 // | |
179 // LexicalDeclaration[In, Yield] : | |
180 // LetOrConst BindingList[?In, ?Yield] ; | |
175 | 181 |
176 switch (peek()) { | 182 switch (peek()) { |
177 case Token::FUNCTION: | 183 case Token::FUNCTION: |
178 return ParseFunctionDeclaration(ok); | 184 return ParseFunctionDeclaration(ok); |
179 case Token::CLASS: | 185 case Token::CLASS: |
180 return ParseClassDeclaration(ok); | 186 return ParseClassDeclaration(ok); |
181 case Token::CONST: | 187 case Token::CONST: |
182 return ParseVariableStatement(kSourceElement, ok); | 188 return ParseVariableStatement(kSourceElement, ok); |
183 case Token::LET: | 189 case Token::LET: |
184 DCHECK(allow_harmony_scoping()); | 190 DCHECK(allow_harmony_scoping()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 PreParserTraits::ReportMessageAt(start_location.beg_pos, | 304 PreParserTraits::ReportMessageAt(start_location.beg_pos, |
299 end_location.end_pos, | 305 end_location.end_pos, |
300 "strict_function"); | 306 "strict_function"); |
301 *ok = false; | 307 *ok = false; |
302 return Statement::Default(); | 308 return Statement::Default(); |
303 } else { | 309 } else { |
304 return statement; | 310 return statement; |
305 } | 311 } |
306 } | 312 } |
307 | 313 |
308 case Token::CLASS: | |
309 return ParseClassDeclaration(CHECK_OK); | |
310 | |
311 case Token::DEBUGGER: | 314 case Token::DEBUGGER: |
312 return ParseDebuggerStatement(ok); | 315 return ParseDebuggerStatement(ok); |
313 | 316 |
314 case Token::VAR: | 317 case Token::VAR: |
315 case Token::CONST: | |
316 return ParseVariableStatement(kStatement, ok); | 318 return ParseVariableStatement(kStatement, ok); |
317 | 319 |
318 case Token::LET: | 320 case Token::CONST: |
319 DCHECK(allow_harmony_scoping()); | 321 // In ES6 CONST is not allowed as a Statement , only as a |
320 if (strict_mode() == STRICT) { | 322 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
323 // backwards compatibility. | |
324 if (strict_mode() == SLOPPY) { | |
321 return ParseVariableStatement(kStatement, ok); | 325 return ParseVariableStatement(kStatement, ok); |
322 } | 326 } |
323 // Fall through. | 327 |
328 // Fall through. | |
324 default: | 329 default: |
325 return ParseExpressionOrLabelledStatement(ok); | 330 return ParseExpressionOrLabelledStatement(ok); |
326 } | 331 } |
327 } | 332 } |
328 | 333 |
329 | 334 |
330 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 335 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
331 // FunctionDeclaration :: | 336 // FunctionDeclaration :: |
332 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 337 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
333 // GeneratorDeclaration :: | 338 // GeneratorDeclaration :: |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 // | 440 // |
436 // * It is a Syntax Error if the code that matches this production is not | 441 // * It is a Syntax Error if the code that matches this production is not |
437 // contained in extended code. | 442 // contained in extended code. |
438 // | 443 // |
439 // However disallowing const in sloppy mode will break compatibility with | 444 // However disallowing const in sloppy mode will break compatibility with |
440 // existing pages. Therefore we keep allowing const with the old | 445 // existing pages. Therefore we keep allowing const with the old |
441 // non-harmony semantics in sloppy mode. | 446 // non-harmony semantics in sloppy mode. |
442 Consume(Token::CONST); | 447 Consume(Token::CONST); |
443 if (strict_mode() == STRICT) { | 448 if (strict_mode() == STRICT) { |
444 if (allow_harmony_scoping()) { | 449 if (allow_harmony_scoping()) { |
445 if (var_context != kSourceElement && var_context != kForStatement) { | 450 if (var_context != kSourceElement && var_context != kForStatement) { |
adamk
2015/01/23 20:11:39
Same dead code as in parser...
| |
446 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); | 451 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); |
447 *ok = false; | 452 *ok = false; |
448 return Statement::Default(); | 453 return Statement::Default(); |
449 } | 454 } |
450 is_strict_const = true; | 455 is_strict_const = true; |
451 require_initializer = var_context != kForStatement; | 456 require_initializer = var_context != kForStatement; |
452 } else { | 457 } else { |
453 Scanner::Location location = scanner()->peek_location(); | 458 Scanner::Location location = scanner()->peek_location(); |
454 ReportMessageAt(location, "strict_const"); | 459 ReportMessageAt(location, "strict_const"); |
455 *ok = false; | 460 *ok = false; |
456 return Statement::Default(); | 461 return Statement::Default(); |
457 } | 462 } |
458 } | 463 } |
459 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 464 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
460 Consume(Token::LET); | 465 Consume(Token::LET); |
461 if (var_context != kSourceElement && var_context != kForStatement) { | 466 if (var_context != kSourceElement && var_context != kForStatement) { |
adamk
2015/01/23 20:11:39
...and here too.
| |
462 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); | 467 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); |
463 *ok = false; | 468 *ok = false; |
464 return Statement::Default(); | 469 return Statement::Default(); |
465 } | 470 } |
466 } else { | 471 } else { |
467 *ok = false; | 472 *ok = false; |
468 return Statement::Default(); | 473 return Statement::Default(); |
469 } | 474 } |
470 | 475 |
471 // The scope of a var/const declared variable anywhere inside a function | 476 // The scope of a var/const declared variable anywhere inside a function |
(...skipping 18 matching lines...) Expand all Loading... | |
490 if (num_decl != NULL) *num_decl = nvars; | 495 if (num_decl != NULL) *num_decl = nvars; |
491 return Statement::Default(); | 496 return Statement::Default(); |
492 } | 497 } |
493 | 498 |
494 | 499 |
495 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 500 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
496 // ExpressionStatement | LabelledStatement :: | 501 // ExpressionStatement | LabelledStatement :: |
497 // Expression ';' | 502 // Expression ';' |
498 // Identifier ':' Statement | 503 // Identifier ':' Statement |
499 | 504 |
505 switch (peek()) { | |
506 case Token::FUNCTION: | |
507 case Token::LBRACE: | |
508 UNREACHABLE(); // Always handled by the callers. | |
509 case Token::CLASS: | |
510 ReportUnexpectedToken(Next()); | |
511 *ok = false; | |
512 return Statement::Default(); | |
513 | |
514 // TODO(arv): Handle `let [` | |
515 // https://code.google.com/p/v8/issues/detail?id=3847 | |
516 | |
517 default: | |
518 break; | |
519 } | |
520 | |
500 bool starts_with_identifier = peek_any_identifier(); | 521 bool starts_with_identifier = peek_any_identifier(); |
501 Expression expr = ParseExpression(true, CHECK_OK); | 522 Expression expr = ParseExpression(true, CHECK_OK); |
502 // Even if the expression starts with an identifier, it is not necessarily an | 523 // Even if the expression starts with an identifier, it is not necessarily an |
503 // identifier. For example, "foo + bar" starts with an identifier but is not | 524 // identifier. For example, "foo + bar" starts with an identifier but is not |
504 // an identifier. | 525 // an identifier. |
505 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 526 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
506 // Expression is a single identifier, and not, e.g., a parenthesized | 527 // Expression is a single identifier, and not, e.g., a parenthesized |
507 // identifier. | 528 // identifier. |
508 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 529 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
509 DCHECK(strict_mode() == SLOPPY || | 530 DCHECK(strict_mode() == SLOPPY || |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1014 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1035 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1015 ParseArguments(ok); | 1036 ParseArguments(ok); |
1016 | 1037 |
1017 return Expression::Default(); | 1038 return Expression::Default(); |
1018 } | 1039 } |
1019 | 1040 |
1020 #undef CHECK_OK | 1041 #undef CHECK_OK |
1021 | 1042 |
1022 | 1043 |
1023 } } // v8::internal | 1044 } } // v8::internal |
OLD | NEW |