| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 bool name_is_strict_reserved, FunctionKind kind, | 95 bool name_is_strict_reserved, FunctionKind kind, |
| 96 int function_token_position, FunctionLiteral::FunctionType type, | 96 int function_token_position, FunctionLiteral::FunctionType type, |
| 97 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 97 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
| 98 return pre_parser_->ParseFunctionLiteral( | 98 return pre_parser_->ParseFunctionLiteral( |
| 99 name, function_name_location, name_is_strict_reserved, kind, | 99 name, function_name_location, name_is_strict_reserved, kind, |
| 100 function_token_position, type, arity_restriction, ok); | 100 function_token_position, type, arity_restriction, ok); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 104 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| 105 StrictMode strict_mode, bool is_generator, ParserRecorder* log) { | 105 LanguageMode language_mode, bool is_generator, ParserRecorder* log) { |
| 106 log_ = log; | 106 log_ = log; |
| 107 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 107 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
| 108 PreParserScope top_scope(scope_, SCRIPT_SCOPE); | 108 PreParserScope top_scope(scope_, SCRIPT_SCOPE); |
| 109 PreParserFactory top_factory(NULL); | 109 PreParserFactory top_factory(NULL); |
| 110 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory); | 110 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory); |
| 111 scope_->SetStrictMode(strict_mode); | 111 scope_->SetLanguageMode(language_mode); |
| 112 PreParserScope function_scope(scope_, FUNCTION_SCOPE); | 112 PreParserScope function_scope(scope_, FUNCTION_SCOPE); |
| 113 PreParserFactory function_factory(NULL); | 113 PreParserFactory function_factory(NULL); |
| 114 FunctionState function_state(&function_state_, &scope_, &function_scope, | 114 FunctionState function_state(&function_state_, &scope_, &function_scope, |
| 115 &function_factory); | 115 &function_factory); |
| 116 function_state.set_is_generator(is_generator); | 116 function_state.set_is_generator(is_generator); |
| 117 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 117 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 118 bool ok = true; | 118 bool ok = true; |
| 119 int start_position = peek_position(); | 119 int start_position = peek_position(); |
| 120 ParseLazyFunctionLiteralBody(&ok); | 120 ParseLazyFunctionLiteralBody(&ok); |
| 121 if (stack_overflow()) return kPreParseStackOverflow; | 121 if (stack_overflow()) return kPreParseStackOverflow; |
| 122 if (!ok) { | 122 if (!ok) { |
| 123 ReportUnexpectedToken(scanner()->current_token()); | 123 ReportUnexpectedToken(scanner()->current_token()); |
| 124 } else { | 124 } else { |
| 125 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 125 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| 126 if (scope_->strict_mode() == STRICT) { | 126 if (is_strict(scope_->language_mode())) { |
| 127 int end_pos = scanner()->location().end_pos; | 127 int end_pos = scanner()->location().end_pos; |
| 128 CheckStrictOctalLiteral(start_position, end_pos, &ok); | 128 CheckStrictOctalLiteral(start_position, end_pos, &ok); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 return kPreParseSuccess; | 131 return kPreParseSuccess; |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 PreParserExpression PreParserTraits::ParseClassLiteral( | 135 PreParserExpression PreParserTraits::ParseClassLiteral( |
| 136 PreParserIdentifier name, Scanner::Location class_name_location, | 136 PreParserIdentifier name, Scanner::Location class_name_location, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 | 181 |
| 182 switch (peek()) { | 182 switch (peek()) { |
| 183 case Token::FUNCTION: | 183 case Token::FUNCTION: |
| 184 return ParseFunctionDeclaration(ok); | 184 return ParseFunctionDeclaration(ok); |
| 185 case Token::CLASS: | 185 case Token::CLASS: |
| 186 return ParseClassDeclaration(ok); | 186 return ParseClassDeclaration(ok); |
| 187 case Token::CONST: | 187 case Token::CONST: |
| 188 return ParseVariableStatement(kSourceElement, ok); | 188 return ParseVariableStatement(kSourceElement, ok); |
| 189 case Token::LET: | 189 case Token::LET: |
| 190 DCHECK(allow_harmony_scoping()); | 190 DCHECK(allow_harmony_scoping()); |
| 191 if (strict_mode() == STRICT) { | 191 if (is_strict(language_mode())) { |
| 192 return ParseVariableStatement(kSourceElement, ok); | 192 return ParseVariableStatement(kSourceElement, ok); |
| 193 } | 193 } |
| 194 // Fall through. | 194 // Fall through. |
| 195 default: | 195 default: |
| 196 return ParseStatement(ok); | 196 return ParseStatement(ok); |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 | 199 |
| 200 | 200 |
| 201 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 201 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
| 202 bool* ok) { | 202 bool* ok) { |
| 203 // SourceElements :: | 203 // SourceElements :: |
| 204 // (Statement)* <end_token> | 204 // (Statement)* <end_token> |
| 205 | 205 |
| 206 bool directive_prologue = true; | 206 bool directive_prologue = true; |
| 207 while (peek() != end_token) { | 207 while (peek() != end_token) { |
| 208 if (directive_prologue && peek() != Token::STRING) { | 208 if (directive_prologue && peek() != Token::STRING) { |
| 209 directive_prologue = false; | 209 directive_prologue = false; |
| 210 } | 210 } |
| 211 Statement statement = ParseSourceElement(CHECK_OK); | 211 Statement statement = ParseSourceElement(CHECK_OK); |
| 212 if (directive_prologue) { | 212 if (directive_prologue) { |
| 213 if (statement.IsUseStrictLiteral()) { | 213 if (statement.IsUseStrictLiteral()) { |
| 214 scope_->SetStrictMode(STRICT); | 214 scope_->SetLanguageMode( |
| 215 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
| 215 } else if (!statement.IsStringLiteral()) { | 216 } else if (!statement.IsStringLiteral()) { |
| 216 directive_prologue = false; | 217 directive_prologue = false; |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 } | 220 } |
| 220 return kUnknownSourceElements; | 221 return kUnknownSourceElements; |
| 221 } | 222 } |
| 222 | 223 |
| 223 | 224 |
| 224 #undef CHECK_OK | 225 #undef CHECK_OK |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 case Token::THROW: | 294 case Token::THROW: |
| 294 return ParseThrowStatement(ok); | 295 return ParseThrowStatement(ok); |
| 295 | 296 |
| 296 case Token::TRY: | 297 case Token::TRY: |
| 297 return ParseTryStatement(ok); | 298 return ParseTryStatement(ok); |
| 298 | 299 |
| 299 case Token::FUNCTION: { | 300 case Token::FUNCTION: { |
| 300 Scanner::Location start_location = scanner()->peek_location(); | 301 Scanner::Location start_location = scanner()->peek_location(); |
| 301 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 302 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
| 302 Scanner::Location end_location = scanner()->location(); | 303 Scanner::Location end_location = scanner()->location(); |
| 303 if (strict_mode() == STRICT) { | 304 if (is_strict(language_mode())) { |
| 304 PreParserTraits::ReportMessageAt(start_location.beg_pos, | 305 PreParserTraits::ReportMessageAt(start_location.beg_pos, |
| 305 end_location.end_pos, | 306 end_location.end_pos, |
| 306 "strict_function"); | 307 "strict_function"); |
| 307 *ok = false; | 308 *ok = false; |
| 308 return Statement::Default(); | 309 return Statement::Default(); |
| 309 } else { | 310 } else { |
| 310 return statement; | 311 return statement; |
| 311 } | 312 } |
| 312 } | 313 } |
| 313 | 314 |
| 314 case Token::DEBUGGER: | 315 case Token::DEBUGGER: |
| 315 return ParseDebuggerStatement(ok); | 316 return ParseDebuggerStatement(ok); |
| 316 | 317 |
| 317 case Token::VAR: | 318 case Token::VAR: |
| 318 return ParseVariableStatement(kStatement, ok); | 319 return ParseVariableStatement(kStatement, ok); |
| 319 | 320 |
| 320 case Token::CONST: | 321 case Token::CONST: |
| 321 // In ES6 CONST is not allowed as a Statement, only as a | 322 // In ES6 CONST is not allowed as a Statement, only as a |
| 322 // LexicalDeclaration, however we continue to allow it in sloppy mode for | 323 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
| 323 // backwards compatibility. | 324 // backwards compatibility. |
| 324 if (strict_mode() == SLOPPY) { | 325 if (is_sloppy(language_mode())) { |
| 325 return ParseVariableStatement(kStatement, ok); | 326 return ParseVariableStatement(kStatement, ok); |
| 326 } | 327 } |
| 327 | 328 |
| 328 // Fall through. | 329 // Fall through. |
| 329 default: | 330 default: |
| 330 return ParseExpressionOrLabelledStatement(ok); | 331 return ParseExpressionOrLabelledStatement(ok); |
| 331 } | 332 } |
| 332 } | 333 } |
| 333 | 334 |
| 334 | 335 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 348 is_generator ? FunctionKind::kGeneratorFunction | 349 is_generator ? FunctionKind::kGeneratorFunction |
| 349 : FunctionKind::kNormalFunction, | 350 : FunctionKind::kNormalFunction, |
| 350 pos, FunctionLiteral::DECLARATION, | 351 pos, FunctionLiteral::DECLARATION, |
| 351 FunctionLiteral::NORMAL_ARITY, CHECK_OK); | 352 FunctionLiteral::NORMAL_ARITY, CHECK_OK); |
| 352 return Statement::FunctionDeclaration(); | 353 return Statement::FunctionDeclaration(); |
| 353 } | 354 } |
| 354 | 355 |
| 355 | 356 |
| 356 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { | 357 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { |
| 357 Expect(Token::CLASS, CHECK_OK); | 358 Expect(Token::CLASS, CHECK_OK); |
| 358 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { | 359 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 359 ReportMessage("sloppy_lexical"); | 360 ReportMessage("sloppy_lexical"); |
| 360 *ok = false; | 361 *ok = false; |
| 361 return Statement::Default(); | 362 return Statement::Default(); |
| 362 } | 363 } |
| 363 | 364 |
| 364 int pos = position(); | 365 int pos = position(); |
| 365 bool is_strict_reserved = false; | 366 bool is_strict_reserved = false; |
| 366 Identifier name = | 367 Identifier name = |
| 367 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 368 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 368 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, | 369 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, |
| 369 CHECK_OK); | 370 CHECK_OK); |
| 370 return Statement::Default(); | 371 return Statement::Default(); |
| 371 } | 372 } |
| 372 | 373 |
| 373 | 374 |
| 374 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 375 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| 375 // Block :: | 376 // Block :: |
| 376 // '{' Statement* '}' | 377 // '{' Statement* '}' |
| 377 | 378 |
| 378 // Note that a Block does not introduce a new execution scope! | 379 // Note that a Block does not introduce a new execution scope! |
| 379 // (ECMA-262, 3rd, 12.2) | 380 // (ECMA-262, 3rd, 12.2) |
| 380 // | 381 // |
| 381 Expect(Token::LBRACE, CHECK_OK); | 382 Expect(Token::LBRACE, CHECK_OK); |
| 382 while (peek() != Token::RBRACE) { | 383 while (peek() != Token::RBRACE) { |
| 383 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 384 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 384 ParseSourceElement(CHECK_OK); | 385 ParseSourceElement(CHECK_OK); |
| 385 } else { | 386 } else { |
| 386 ParseStatement(CHECK_OK); | 387 ParseStatement(CHECK_OK); |
| 387 } | 388 } |
| 388 } | 389 } |
| 389 Expect(Token::RBRACE, ok); | 390 Expect(Token::RBRACE, ok); |
| 390 return Statement::Default(); | 391 return Statement::Default(); |
| 391 } | 392 } |
| 392 | 393 |
| 393 | 394 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 // | 439 // |
| 439 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 440 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 440 // | 441 // |
| 441 // * It is a Syntax Error if the code that matches this production is not | 442 // * It is a Syntax Error if the code that matches this production is not |
| 442 // contained in extended code. | 443 // contained in extended code. |
| 443 // | 444 // |
| 444 // However disallowing const in sloppy mode will break compatibility with | 445 // However disallowing const in sloppy mode will break compatibility with |
| 445 // existing pages. Therefore we keep allowing const with the old | 446 // existing pages. Therefore we keep allowing const with the old |
| 446 // non-harmony semantics in sloppy mode. | 447 // non-harmony semantics in sloppy mode. |
| 447 Consume(Token::CONST); | 448 Consume(Token::CONST); |
| 448 if (strict_mode() == STRICT) { | 449 if (is_strict(language_mode())) { |
| 449 DCHECK(var_context != kStatement); | 450 DCHECK(var_context != kStatement); |
| 450 if (!allow_harmony_scoping()) { | 451 if (!allow_harmony_scoping()) { |
| 451 Scanner::Location location = scanner()->peek_location(); | 452 Scanner::Location location = scanner()->peek_location(); |
| 452 ReportMessageAt(location, "strict_const"); | 453 ReportMessageAt(location, "strict_const"); |
| 453 *ok = false; | 454 *ok = false; |
| 454 return Statement::Default(); | 455 return Statement::Default(); |
| 455 } | 456 } |
| 456 is_strict_const = true; | 457 is_strict_const = true; |
| 457 require_initializer = var_context != kForStatement; | 458 require_initializer = var_context != kForStatement; |
| 458 } | 459 } |
| 459 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 460 } else if (peek() == Token::LET && is_strict(language_mode())) { |
| 460 Consume(Token::LET); | 461 Consume(Token::LET); |
| 461 DCHECK(var_context != kStatement); | 462 DCHECK(var_context != kStatement); |
| 462 } else { | 463 } else { |
| 463 *ok = false; | 464 *ok = false; |
| 464 return Statement::Default(); | 465 return Statement::Default(); |
| 465 } | 466 } |
| 466 | 467 |
| 467 // The scope of a var/const declared variable anywhere inside a function | 468 // The scope of a var/const declared variable anywhere inside a function |
| 468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 469 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 469 // of a let declared variable is the scope of the immediately enclosing | 470 // of a let declared variable is the scope of the immediately enclosing |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 | 512 |
| 512 bool starts_with_identifier = peek_any_identifier(); | 513 bool starts_with_identifier = peek_any_identifier(); |
| 513 Expression expr = ParseExpression(true, CHECK_OK); | 514 Expression expr = ParseExpression(true, CHECK_OK); |
| 514 // Even if the expression starts with an identifier, it is not necessarily an | 515 // Even if the expression starts with an identifier, it is not necessarily an |
| 515 // identifier. For example, "foo + bar" starts with an identifier but is not | 516 // identifier. For example, "foo + bar" starts with an identifier but is not |
| 516 // an identifier. | 517 // an identifier. |
| 517 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 518 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
| 518 // Expression is a single identifier, and not, e.g., a parenthesized | 519 // Expression is a single identifier, and not, e.g., a parenthesized |
| 519 // identifier. | 520 // identifier. |
| 520 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 521 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
| 521 DCHECK(strict_mode() == SLOPPY || | 522 DCHECK(is_sloppy(language_mode()) || |
| 522 !IsFutureStrictReserved(expr.AsIdentifier())); | 523 !IsFutureStrictReserved(expr.AsIdentifier())); |
| 523 Consume(Token::COLON); | 524 Consume(Token::COLON); |
| 524 return ParseStatement(ok); | 525 return ParseStatement(ok); |
| 525 // Preparsing is disabled for extensions (because the extension details | 526 // Preparsing is disabled for extensions (because the extension details |
| 526 // aren't passed to lazily compiled functions), so we don't | 527 // aren't passed to lazily compiled functions), so we don't |
| 527 // accept "native function" in the preparser. | 528 // accept "native function" in the preparser. |
| 528 } | 529 } |
| 529 // Parsed expression statement. | 530 // Parsed expression statement. |
| 530 // Detect attempts at 'let' declarations in sloppy mode. | 531 // Detect attempts at 'let' declarations in sloppy mode. |
| 531 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && | 532 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
| 532 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { | 533 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { |
| 533 ReportMessage("sloppy_lexical", NULL); | 534 ReportMessage("sloppy_lexical", NULL); |
| 534 *ok = false; | 535 *ok = false; |
| 535 return Statement::Default(); | 536 return Statement::Default(); |
| 536 } | 537 } |
| 537 ExpectSemicolon(CHECK_OK); | 538 ExpectSemicolon(CHECK_OK); |
| 538 return Statement::ExpressionStatement(expr); | 539 return Statement::ExpressionStatement(expr); |
| 539 } | 540 } |
| 540 | 541 |
| 541 | 542 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 } | 616 } |
| 616 ExpectSemicolon(CHECK_OK); | 617 ExpectSemicolon(CHECK_OK); |
| 617 return Statement::Default(); | 618 return Statement::Default(); |
| 618 } | 619 } |
| 619 | 620 |
| 620 | 621 |
| 621 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 622 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 622 // WithStatement :: | 623 // WithStatement :: |
| 623 // 'with' '(' Expression ')' Statement | 624 // 'with' '(' Expression ')' Statement |
| 624 Expect(Token::WITH, CHECK_OK); | 625 Expect(Token::WITH, CHECK_OK); |
| 625 if (strict_mode() == STRICT) { | 626 if (is_strict(language_mode())) { |
| 626 ReportMessageAt(scanner()->location(), "strict_mode_with"); | 627 ReportMessageAt(scanner()->location(), "strict_mode_with"); |
| 627 *ok = false; | 628 *ok = false; |
| 628 return Statement::Default(); | 629 return Statement::Default(); |
| 629 } | 630 } |
| 630 Expect(Token::LPAREN, CHECK_OK); | 631 Expect(Token::LPAREN, CHECK_OK); |
| 631 ParseExpression(true, CHECK_OK); | 632 ParseExpression(true, CHECK_OK); |
| 632 Expect(Token::RPAREN, CHECK_OK); | 633 Expect(Token::RPAREN, CHECK_OK); |
| 633 | 634 |
| 634 PreParserScope with_scope(scope_, WITH_SCOPE); | 635 PreParserScope with_scope(scope_, WITH_SCOPE); |
| 635 BlockState block_state(&scope_, &with_scope); | 636 BlockState block_state(&scope_, &with_scope); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 | 710 |
| 710 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 711 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 711 // ForStatement :: | 712 // ForStatement :: |
| 712 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 713 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 713 | 714 |
| 714 Expect(Token::FOR, CHECK_OK); | 715 Expect(Token::FOR, CHECK_OK); |
| 715 Expect(Token::LPAREN, CHECK_OK); | 716 Expect(Token::LPAREN, CHECK_OK); |
| 716 bool is_let_identifier_expression = false; | 717 bool is_let_identifier_expression = false; |
| 717 if (peek() != Token::SEMICOLON) { | 718 if (peek() != Token::SEMICOLON) { |
| 718 if (peek() == Token::VAR || peek() == Token::CONST || | 719 if (peek() == Token::VAR || peek() == Token::CONST || |
| 719 (peek() == Token::LET && strict_mode() == STRICT)) { | 720 (peek() == Token::LET && is_strict(language_mode()))) { |
| 720 bool is_lexical = peek() == Token::LET || | 721 bool is_lexical = peek() == Token::LET || |
| 721 (peek() == Token::CONST && strict_mode() == STRICT); | 722 (peek() == Token::CONST && is_strict(language_mode())); |
| 722 int decl_count; | 723 int decl_count; |
| 723 VariableDeclarationProperties decl_props = kHasNoInitializers; | 724 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 724 ParseVariableDeclarations( | 725 ParseVariableDeclarations( |
| 725 kForStatement, &decl_props, &decl_count, CHECK_OK); | 726 kForStatement, &decl_props, &decl_count, CHECK_OK); |
| 726 bool has_initializers = decl_props == kHasInitializers; | 727 bool has_initializers = decl_props == kHasInitializers; |
| 727 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); | 728 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); |
| 728 bool accept_OF = !has_initializers; | 729 bool accept_OF = !has_initializers; |
| 729 if (accept_IN && CheckInOrOf(accept_OF)) { | 730 if (accept_IN && CheckInOrOf(accept_OF)) { |
| 730 ParseExpression(true, CHECK_OK); | 731 ParseExpression(true, CHECK_OK); |
| 731 Expect(Token::RPAREN, CHECK_OK); | 732 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 742 Expect(Token::RPAREN, CHECK_OK); | 743 Expect(Token::RPAREN, CHECK_OK); |
| 743 | 744 |
| 744 ParseStatement(CHECK_OK); | 745 ParseStatement(CHECK_OK); |
| 745 return Statement::Default(); | 746 return Statement::Default(); |
| 746 } | 747 } |
| 747 } | 748 } |
| 748 } | 749 } |
| 749 | 750 |
| 750 // Parsed initializer at this point. | 751 // Parsed initializer at this point. |
| 751 // Detect attempts at 'let' declarations in sloppy mode. | 752 // Detect attempts at 'let' declarations in sloppy mode. |
| 752 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && | 753 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
| 753 is_let_identifier_expression) { | 754 is_let_identifier_expression) { |
| 754 ReportMessage("sloppy_lexical", NULL); | 755 ReportMessage("sloppy_lexical", NULL); |
| 755 *ok = false; | 756 *ok = false; |
| 756 return Statement::Default(); | 757 return Statement::Default(); |
| 757 } | 758 } |
| 758 Expect(Token::SEMICOLON, CHECK_OK); | 759 Expect(Token::SEMICOLON, CHECK_OK); |
| 759 | 760 |
| 760 if (peek() != Token::SEMICOLON) { | 761 if (peek() != Token::SEMICOLON) { |
| 761 ParseExpression(true, CHECK_OK); | 762 ParseExpression(true, CHECK_OK); |
| 762 } | 763 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 if (is_lazily_parsed) { | 928 if (is_lazily_parsed) { |
| 928 ParseLazyFunctionLiteralBody(CHECK_OK); | 929 ParseLazyFunctionLiteralBody(CHECK_OK); |
| 929 } else { | 930 } else { |
| 930 ParseSourceElements(Token::RBRACE, ok); | 931 ParseSourceElements(Token::RBRACE, ok); |
| 931 } | 932 } |
| 932 Expect(Token::RBRACE, CHECK_OK); | 933 Expect(Token::RBRACE, CHECK_OK); |
| 933 | 934 |
| 934 // Validate strict mode. We can do this only after parsing the function, | 935 // Validate strict mode. We can do this only after parsing the function, |
| 935 // since the function can declare itself strict. | 936 // since the function can declare itself strict. |
| 936 // Concise methods use StrictFormalParameters. | 937 // Concise methods use StrictFormalParameters. |
| 937 if (strict_mode() == STRICT || IsConciseMethod(kind) || is_rest) { | 938 if (is_strict(language_mode()) || IsConciseMethod(kind) || is_rest) { |
| 938 if (function_name.IsEvalOrArguments()) { | 939 if (function_name.IsEvalOrArguments()) { |
| 939 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 940 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
| 940 *ok = false; | 941 *ok = false; |
| 941 return Expression::Default(); | 942 return Expression::Default(); |
| 942 } | 943 } |
| 943 if (name_is_strict_reserved) { | 944 if (name_is_strict_reserved) { |
| 944 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 945 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
| 945 *ok = false; | 946 *ok = false; |
| 946 return Expression::Default(); | 947 return Expression::Default(); |
| 947 } | 948 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 970 | 971 |
| 971 | 972 |
| 972 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 973 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
| 973 int body_start = position(); | 974 int body_start = position(); |
| 974 ParseSourceElements(Token::RBRACE, ok); | 975 ParseSourceElements(Token::RBRACE, ok); |
| 975 if (!*ok) return; | 976 if (!*ok) return; |
| 976 | 977 |
| 977 // Position right after terminal '}'. | 978 // Position right after terminal '}'. |
| 978 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 979 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| 979 int body_end = scanner()->peek_location().end_pos; | 980 int body_end = scanner()->peek_location().end_pos; |
| 980 log_->LogFunction(body_start, body_end, | 981 log_->LogFunction( |
| 981 function_state_->materialized_literal_count(), | 982 body_start, body_end, function_state_->materialized_literal_count(), |
| 982 function_state_->expected_property_count(), | 983 function_state_->expected_property_count(), language_mode()); |
| 983 strict_mode()); | |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 PreParserExpression PreParser::ParseClassLiteral( | 987 PreParserExpression PreParser::ParseClassLiteral( |
| 988 PreParserIdentifier name, Scanner::Location class_name_location, | 988 PreParserIdentifier name, Scanner::Location class_name_location, |
| 989 bool name_is_strict_reserved, int pos, bool* ok) { | 989 bool name_is_strict_reserved, int pos, bool* ok) { |
| 990 // All parts of a ClassDeclaration and ClassExpression are strict code. | 990 // All parts of a ClassDeclaration and ClassExpression are strict code. |
| 991 if (name_is_strict_reserved) { | 991 if (name_is_strict_reserved) { |
| 992 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 992 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
| 993 *ok = false; | 993 *ok = false; |
| 994 return EmptyExpression(); | 994 return EmptyExpression(); |
| 995 } | 995 } |
| 996 if (IsEvalOrArguments(name)) { | 996 if (IsEvalOrArguments(name)) { |
| 997 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 997 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
| 998 *ok = false; | 998 *ok = false; |
| 999 return EmptyExpression(); | 999 return EmptyExpression(); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 PreParserScope scope = NewScope(scope_, BLOCK_SCOPE); | 1002 PreParserScope scope = NewScope(scope_, BLOCK_SCOPE); |
| 1003 BlockState block_state(&scope_, &scope); | 1003 BlockState block_state(&scope_, &scope); |
| 1004 scope_->SetStrictMode(STRICT); | 1004 scope_->SetLanguageMode( |
| 1005 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
| 1005 scope_->SetScopeName(name); | 1006 scope_->SetScopeName(name); |
| 1006 | 1007 |
| 1007 bool has_extends = Check(Token::EXTENDS); | 1008 bool has_extends = Check(Token::EXTENDS); |
| 1008 if (has_extends) { | 1009 if (has_extends) { |
| 1009 ParseLeftHandSideExpression(CHECK_OK); | 1010 ParseLeftHandSideExpression(CHECK_OK); |
| 1010 } | 1011 } |
| 1011 | 1012 |
| 1012 ClassLiteralChecker checker(this); | 1013 ClassLiteralChecker checker(this); |
| 1013 bool has_seen_constructor = false; | 1014 bool has_seen_constructor = false; |
| 1014 | 1015 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1041 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1042 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1042 ParseArguments(ok); | 1043 ParseArguments(ok); |
| 1043 | 1044 |
| 1044 return Expression::Default(); | 1045 return Expression::Default(); |
| 1045 } | 1046 } |
| 1046 | 1047 |
| 1047 #undef CHECK_OK | 1048 #undef CHECK_OK |
| 1048 | 1049 |
| 1049 | 1050 |
| 1050 } } // v8::internal | 1051 } } // v8::internal |
| OLD | NEW |