| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 namespace internal { | 56 namespace internal { |
| 57 | 57 |
| 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { | 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { |
| 60 log_ = log; | 60 log_ = log; |
| 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
| 62 Scope top_scope(&scope_, kTopLevelScope); | 62 Scope top_scope(&scope_, kTopLevelScope); |
| 63 set_language_mode(mode); | 63 set_language_mode(mode); |
| 64 Scope function_scope(&scope_, kFunctionScope); | 64 Scope function_scope(&scope_, kFunctionScope); |
| 65 function_scope.set_is_generator(is_generator); | 65 function_scope.set_is_generator(is_generator); |
| 66 ASSERT_EQ(i::Token::LBRACE, scanner_->current_token()); | 66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token()); |
| 67 bool ok = true; | 67 bool ok = true; |
| 68 int start_position = scanner_->peek_location().beg_pos; | 68 int start_position = scanner()->peek_location().beg_pos; |
| 69 ParseLazyFunctionLiteralBody(&ok); | 69 ParseLazyFunctionLiteralBody(&ok); |
| 70 if (stack_overflow_) return kPreParseStackOverflow; | 70 if (stack_overflow()) return kPreParseStackOverflow; |
| 71 if (!ok) { | 71 if (!ok) { |
| 72 ReportUnexpectedToken(scanner_->current_token()); | 72 ReportUnexpectedToken(scanner()->current_token()); |
| 73 } else { | 73 } else { |
| 74 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
| 75 if (!is_classic_mode()) { | 75 if (!is_classic_mode()) { |
| 76 int end_pos = scanner_->location().end_pos; | 76 int end_pos = scanner()->location().end_pos; |
| 77 CheckOctalLiteral(start_position, end_pos, &ok); | 77 CheckOctalLiteral(start_position, end_pos, &ok); |
| 78 if (ok) { | 78 if (ok) { |
| 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); | 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 return kPreParseSuccess; | 83 return kPreParseSuccess; |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 // Preparsing checks a JavaScript program and emits preparse-data that helps | 87 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 88 // a later parsing to be faster. | 88 // a later parsing to be faster. |
| 89 // See preparser-data.h for the data. | 89 // See preparser-data.h for the data. |
| 90 | 90 |
| 91 // The PreParser checks that the syntax follows the grammar for JavaScript, | 91 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 92 // and collects some information about the program along the way. | 92 // and collects some information about the program along the way. |
| 93 // The grammar check is only performed in order to understand the program | 93 // The grammar check is only performed in order to understand the program |
| 94 // sufficiently to deduce some information about it, that can be used | 94 // sufficiently to deduce some information about it, that can be used |
| 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 96 // rather it is to speed up properly written and correct programs. | 96 // rather it is to speed up properly written and correct programs. |
| 97 // That means that contextual checks (like a label being declared where | 97 // That means that contextual checks (like a label being declared where |
| 98 // it is used) are generally omitted. | 98 // it is used) are generally omitted. |
| 99 | 99 |
| 100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { | 100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { |
| 101 // We don't report stack overflows here, to avoid increasing the | 101 // We don't report stack overflows here, to avoid increasing the |
| 102 // stack depth even further. Instead we report it after parsing is | 102 // stack depth even further. Instead we report it after parsing is |
| 103 // over, in ParseProgram. | 103 // over, in ParseProgram. |
| 104 if (token == i::Token::ILLEGAL && stack_overflow_) { | 104 if (token == i::Token::ILLEGAL && stack_overflow()) { |
| 105 return; | 105 return; |
| 106 } | 106 } |
| 107 i::Scanner::Location source_location = scanner_->location(); | 107 i::Scanner::Location source_location = scanner()->location(); |
| 108 | 108 |
| 109 // Four of the tokens are treated specially | 109 // Four of the tokens are treated specially |
| 110 switch (token) { | 110 switch (token) { |
| 111 case i::Token::EOS: | 111 case i::Token::EOS: |
| 112 return ReportMessageAt(source_location, "unexpected_eos", NULL); | 112 return ReportMessageAt(source_location, "unexpected_eos", NULL); |
| 113 case i::Token::NUMBER: | 113 case i::Token::NUMBER: |
| 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); | 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); |
| 115 case i::Token::STRING: | 115 case i::Token::STRING: |
| 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); | 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); |
| 117 case i::Token::IDENTIFIER: | 117 case i::Token::IDENTIFIER: |
| 118 return ReportMessageAt(source_location, | 118 return ReportMessageAt(source_location, |
| 119 "unexpected_token_identifier", NULL); | 119 "unexpected_token_identifier", NULL); |
| 120 case i::Token::FUTURE_RESERVED_WORD: | 120 case i::Token::FUTURE_RESERVED_WORD: |
| 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); | 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); |
| 122 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 122 case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| 123 return ReportMessageAt(source_location, | 123 return ReportMessageAt(source_location, |
| 124 "unexpected_strict_reserved", NULL); | 124 "unexpected_strict_reserved", NULL); |
| 125 default: | 125 default: |
| 126 const char* name = i::Token::String(token); | 126 const char* name = i::Token::String(token); |
| 127 ReportMessageAt(source_location, "unexpected_token", name); | 127 ReportMessageAt(source_location, "unexpected_token", name); |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 // Checks whether octal literal last seen is between beg_pos and end_pos. | 132 // Checks whether octal literal last seen is between beg_pos and end_pos. |
| 133 // If so, reports an error. | 133 // If so, reports an error. |
| 134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 135 i::Scanner::Location octal = scanner_->octal_position(); | 135 i::Scanner::Location octal = scanner()->octal_position(); |
| 136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 137 ReportMessageAt(octal, "strict_octal_literal", NULL); | 137 ReportMessageAt(octal, "strict_octal_literal", NULL); |
| 138 scanner_->clear_octal_position(); | 138 scanner()->clear_octal_position(); |
| 139 *ok = false; | 139 *ok = false; |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 #define CHECK_OK ok); \ | 144 #define CHECK_OK ok); \ |
| 145 if (!*ok) return kUnknownSourceElements; \ | 145 if (!*ok) return kUnknownSourceElements; \ |
| 146 ((void)0 | 146 ((void)0 |
| 147 #define DUMMY ) // to make indentation work | 147 #define DUMMY ) // to make indentation work |
| 148 #undef DUMMY | 148 #undef DUMMY |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 case i::Token::SWITCH: | 267 case i::Token::SWITCH: |
| 268 return ParseSwitchStatement(ok); | 268 return ParseSwitchStatement(ok); |
| 269 | 269 |
| 270 case i::Token::THROW: | 270 case i::Token::THROW: |
| 271 return ParseThrowStatement(ok); | 271 return ParseThrowStatement(ok); |
| 272 | 272 |
| 273 case i::Token::TRY: | 273 case i::Token::TRY: |
| 274 return ParseTryStatement(ok); | 274 return ParseTryStatement(ok); |
| 275 | 275 |
| 276 case i::Token::FUNCTION: { | 276 case i::Token::FUNCTION: { |
| 277 i::Scanner::Location start_location = scanner_->peek_location(); | 277 i::Scanner::Location start_location = scanner()->peek_location(); |
| 278 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 278 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
| 279 i::Scanner::Location end_location = scanner_->location(); | 279 i::Scanner::Location end_location = scanner()->location(); |
| 280 if (!is_classic_mode()) { | 280 if (!is_classic_mode()) { |
| 281 ReportMessageAt(start_location.beg_pos, end_location.end_pos, | 281 ReportMessageAt(start_location.beg_pos, end_location.end_pos, |
| 282 "strict_function", NULL); | 282 "strict_function", NULL); |
| 283 *ok = false; | 283 *ok = false; |
| 284 return Statement::Default(); | 284 return Statement::Default(); |
| 285 } else { | 285 } else { |
| 286 return statement; | 286 return statement; |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 | 289 |
| 290 case i::Token::DEBUGGER: | 290 case i::Token::DEBUGGER: |
| 291 return ParseDebuggerStatement(ok); | 291 return ParseDebuggerStatement(ok); |
| 292 | 292 |
| 293 default: | 293 default: |
| 294 return ParseExpressionOrLabelledStatement(ok); | 294 return ParseExpressionOrLabelledStatement(ok); |
| 295 } | 295 } |
| 296 } | 296 } |
| 297 | 297 |
| 298 | 298 |
| 299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
| 300 // FunctionDeclaration :: | 300 // FunctionDeclaration :: |
| 301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 302 // GeneratorDeclaration :: | 302 // GeneratorDeclaration :: |
| 303 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 303 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 304 // '{' FunctionBody '}' | 304 // '{' FunctionBody '}' |
| 305 Expect(i::Token::FUNCTION, CHECK_OK); | 305 Expect(i::Token::FUNCTION, CHECK_OK); |
| 306 | 306 |
| 307 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 307 bool is_generator = allow_generators() && Check(i::Token::MUL); |
| 308 Identifier identifier = ParseIdentifier(CHECK_OK); | 308 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 309 i::Scanner::Location location = scanner_->location(); | 309 i::Scanner::Location location = scanner()->location(); |
| 310 | 310 |
| 311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); | 311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); |
| 312 | 312 |
| 313 if (function_value.IsStrictFunction() && | 313 if (function_value.IsStrictFunction() && |
| 314 !identifier.IsValidStrictVariable()) { | 314 !identifier.IsValidStrictVariable()) { |
| 315 // Strict mode violation, using either reserved word or eval/arguments | 315 // Strict mode violation, using either reserved word or eval/arguments |
| 316 // as name of strict function. | 316 // as name of strict function. |
| 317 const char* type = "strict_function_name"; | 317 const char* type = "strict_function_name"; |
| 318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { |
| 319 type = "strict_reserved_word"; | 319 type = "strict_reserved_word"; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 // contained in extended code. | 395 // contained in extended code. |
| 396 // | 396 // |
| 397 // However disallowing const in classic mode will break compatibility with | 397 // However disallowing const in classic mode will break compatibility with |
| 398 // existing pages. Therefore we keep allowing const with the old | 398 // existing pages. Therefore we keep allowing const with the old |
| 399 // non-harmony semantics in classic mode. | 399 // non-harmony semantics in classic mode. |
| 400 Consume(i::Token::CONST); | 400 Consume(i::Token::CONST); |
| 401 switch (language_mode()) { | 401 switch (language_mode()) { |
| 402 case i::CLASSIC_MODE: | 402 case i::CLASSIC_MODE: |
| 403 break; | 403 break; |
| 404 case i::STRICT_MODE: { | 404 case i::STRICT_MODE: { |
| 405 i::Scanner::Location location = scanner_->peek_location(); | 405 i::Scanner::Location location = scanner()->peek_location(); |
| 406 ReportMessageAt(location, "strict_const", NULL); | 406 ReportMessageAt(location, "strict_const", NULL); |
| 407 *ok = false; | 407 *ok = false; |
| 408 return Statement::Default(); | 408 return Statement::Default(); |
| 409 } | 409 } |
| 410 case i::EXTENDED_MODE: | 410 case i::EXTENDED_MODE: |
| 411 if (var_context != kSourceElement && | 411 if (var_context != kSourceElement && |
| 412 var_context != kForStatement) { | 412 var_context != kForStatement) { |
| 413 i::Scanner::Location location = scanner_->peek_location(); | 413 i::Scanner::Location location = scanner()->peek_location(); |
| 414 ReportMessageAt(location.beg_pos, location.end_pos, | 414 ReportMessageAt(location.beg_pos, location.end_pos, |
| 415 "unprotected_const", NULL); | 415 "unprotected_const", NULL); |
| 416 *ok = false; | 416 *ok = false; |
| 417 return Statement::Default(); | 417 return Statement::Default(); |
| 418 } | 418 } |
| 419 require_initializer = true; | 419 require_initializer = true; |
| 420 break; | 420 break; |
| 421 } | 421 } |
| 422 } else if (peek() == i::Token::LET) { | 422 } else if (peek() == i::Token::LET) { |
| 423 // ES6 Draft Rev4 section 12.2.1: | 423 // ES6 Draft Rev4 section 12.2.1: |
| 424 // | 424 // |
| 425 // LetDeclaration : let LetBindingList ; | 425 // LetDeclaration : let LetBindingList ; |
| 426 // | 426 // |
| 427 // * It is a Syntax Error if the code that matches this production is not | 427 // * It is a Syntax Error if the code that matches this production is not |
| 428 // contained in extended code. | 428 // contained in extended code. |
| 429 if (!is_extended_mode()) { | 429 if (!is_extended_mode()) { |
| 430 i::Scanner::Location location = scanner_->peek_location(); | 430 i::Scanner::Location location = scanner()->peek_location(); |
| 431 ReportMessageAt(location.beg_pos, location.end_pos, | 431 ReportMessageAt(location.beg_pos, location.end_pos, |
| 432 "illegal_let", NULL); | 432 "illegal_let", NULL); |
| 433 *ok = false; | 433 *ok = false; |
| 434 return Statement::Default(); | 434 return Statement::Default(); |
| 435 } | 435 } |
| 436 Consume(i::Token::LET); | 436 Consume(i::Token::LET); |
| 437 if (var_context != kSourceElement && | 437 if (var_context != kSourceElement && |
| 438 var_context != kForStatement) { | 438 var_context != kForStatement) { |
| 439 i::Scanner::Location location = scanner_->peek_location(); | 439 i::Scanner::Location location = scanner()->peek_location(); |
| 440 ReportMessageAt(location.beg_pos, location.end_pos, | 440 ReportMessageAt(location.beg_pos, location.end_pos, |
| 441 "unprotected_let", NULL); | 441 "unprotected_let", NULL); |
| 442 *ok = false; | 442 *ok = false; |
| 443 return Statement::Default(); | 443 return Statement::Default(); |
| 444 } | 444 } |
| 445 } else { | 445 } else { |
| 446 *ok = false; | 446 *ok = false; |
| 447 return Statement::Default(); | 447 return Statement::Default(); |
| 448 } | 448 } |
| 449 | 449 |
| 450 // The scope of a var/const declared variable anywhere inside a function | 450 // The scope of a var/const declared variable anywhere inside a function |
| 451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 452 // of a let declared variable is the scope of the immediately enclosing | 452 // of a let declared variable is the scope of the immediately enclosing |
| 453 // block. | 453 // block. |
| 454 int nvars = 0; // the number of variables declared | 454 int nvars = 0; // the number of variables declared |
| 455 do { | 455 do { |
| 456 // Parse variable name. | 456 // Parse variable name. |
| 457 if (nvars > 0) Consume(i::Token::COMMA); | 457 if (nvars > 0) Consume(i::Token::COMMA); |
| 458 Identifier identifier = ParseIdentifier(CHECK_OK); | 458 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { | 459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { |
| 460 StrictModeIdentifierViolation(scanner_->location(), | 460 StrictModeIdentifierViolation(scanner()->location(), |
| 461 "strict_var_name", | 461 "strict_var_name", |
| 462 identifier, | 462 identifier, |
| 463 ok); | 463 ok); |
| 464 return Statement::Default(); | 464 return Statement::Default(); |
| 465 } | 465 } |
| 466 nvars++; | 466 nvars++; |
| 467 if (peek() == i::Token::ASSIGN || require_initializer) { | 467 if (peek() == i::Token::ASSIGN || require_initializer) { |
| 468 Expect(i::Token::ASSIGN, CHECK_OK); | 468 Expect(i::Token::ASSIGN, CHECK_OK); |
| 469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 470 if (decl_props != NULL) *decl_props = kHasInitializers; | 470 if (decl_props != NULL) *decl_props = kHasInitializers; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 return Statement::Default(); | 517 return Statement::Default(); |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
| 522 // ContinueStatement :: | 522 // ContinueStatement :: |
| 523 // 'continue' [no line terminator] Identifier? ';' | 523 // 'continue' [no line terminator] Identifier? ';' |
| 524 | 524 |
| 525 Expect(i::Token::CONTINUE, CHECK_OK); | 525 Expect(i::Token::CONTINUE, CHECK_OK); |
| 526 i::Token::Value tok = peek(); | 526 i::Token::Value tok = peek(); |
| 527 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 527 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 528 tok != i::Token::SEMICOLON && | 528 tok != i::Token::SEMICOLON && |
| 529 tok != i::Token::RBRACE && | 529 tok != i::Token::RBRACE && |
| 530 tok != i::Token::EOS) { | 530 tok != i::Token::EOS) { |
| 531 ParseIdentifier(CHECK_OK); | 531 ParseIdentifier(CHECK_OK); |
| 532 } | 532 } |
| 533 ExpectSemicolon(CHECK_OK); | 533 ExpectSemicolon(CHECK_OK); |
| 534 return Statement::Default(); | 534 return Statement::Default(); |
| 535 } | 535 } |
| 536 | 536 |
| 537 | 537 |
| 538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 539 // BreakStatement :: | 539 // BreakStatement :: |
| 540 // 'break' [no line terminator] Identifier? ';' | 540 // 'break' [no line terminator] Identifier? ';' |
| 541 | 541 |
| 542 Expect(i::Token::BREAK, CHECK_OK); | 542 Expect(i::Token::BREAK, CHECK_OK); |
| 543 i::Token::Value tok = peek(); | 543 i::Token::Value tok = peek(); |
| 544 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 544 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 545 tok != i::Token::SEMICOLON && | 545 tok != i::Token::SEMICOLON && |
| 546 tok != i::Token::RBRACE && | 546 tok != i::Token::RBRACE && |
| 547 tok != i::Token::EOS) { | 547 tok != i::Token::EOS) { |
| 548 ParseIdentifier(CHECK_OK); | 548 ParseIdentifier(CHECK_OK); |
| 549 } | 549 } |
| 550 ExpectSemicolon(CHECK_OK); | 550 ExpectSemicolon(CHECK_OK); |
| 551 return Statement::Default(); | 551 return Statement::Default(); |
| 552 } | 552 } |
| 553 | 553 |
| 554 | 554 |
| 555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 556 // ReturnStatement :: | 556 // ReturnStatement :: |
| 557 // 'return' [no line terminator] Expression? ';' | 557 // 'return' [no line terminator] Expression? ';' |
| 558 | 558 |
| 559 // Consume the return token. It is necessary to do the before | 559 // Consume the return token. It is necessary to do the before |
| 560 // reporting any errors on it, because of the way errors are | 560 // reporting any errors on it, because of the way errors are |
| 561 // reported (underlining). | 561 // reported (underlining). |
| 562 Expect(i::Token::RETURN, CHECK_OK); | 562 Expect(i::Token::RETURN, CHECK_OK); |
| 563 | 563 |
| 564 // An ECMAScript program is considered syntactically incorrect if it | 564 // An ECMAScript program is considered syntactically incorrect if it |
| 565 // contains a return statement that is not within the body of a | 565 // contains a return statement that is not within the body of a |
| 566 // function. See ECMA-262, section 12.9, page 67. | 566 // function. See ECMA-262, section 12.9, page 67. |
| 567 // This is not handled during preparsing. | 567 // This is not handled during preparsing. |
| 568 | 568 |
| 569 i::Token::Value tok = peek(); | 569 i::Token::Value tok = peek(); |
| 570 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 570 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 571 tok != i::Token::SEMICOLON && | 571 tok != i::Token::SEMICOLON && |
| 572 tok != i::Token::RBRACE && | 572 tok != i::Token::RBRACE && |
| 573 tok != i::Token::EOS) { | 573 tok != i::Token::EOS) { |
| 574 ParseExpression(true, CHECK_OK); | 574 ParseExpression(true, CHECK_OK); |
| 575 } | 575 } |
| 576 ExpectSemicolon(CHECK_OK); | 576 ExpectSemicolon(CHECK_OK); |
| 577 return Statement::Default(); | 577 return Statement::Default(); |
| 578 } | 578 } |
| 579 | 579 |
| 580 | 580 |
| 581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 582 // WithStatement :: | 582 // WithStatement :: |
| 583 // 'with' '(' Expression ')' Statement | 583 // 'with' '(' Expression ')' Statement |
| 584 Expect(i::Token::WITH, CHECK_OK); | 584 Expect(i::Token::WITH, CHECK_OK); |
| 585 if (!is_classic_mode()) { | 585 if (!is_classic_mode()) { |
| 586 i::Scanner::Location location = scanner_->location(); | 586 i::Scanner::Location location = scanner()->location(); |
| 587 ReportMessageAt(location, "strict_mode_with", NULL); | 587 ReportMessageAt(location, "strict_mode_with", NULL); |
| 588 *ok = false; | 588 *ok = false; |
| 589 return Statement::Default(); | 589 return Statement::Default(); |
| 590 } | 590 } |
| 591 Expect(i::Token::LPAREN, CHECK_OK); | 591 Expect(i::Token::LPAREN, CHECK_OK); |
| 592 ParseExpression(true, CHECK_OK); | 592 ParseExpression(true, CHECK_OK); |
| 593 Expect(i::Token::RPAREN, CHECK_OK); | 593 Expect(i::Token::RPAREN, CHECK_OK); |
| 594 | 594 |
| 595 Scope::InsideWith iw(scope_); | 595 Scope::InsideWith iw(scope_); |
| 596 ParseStatement(CHECK_OK); | 596 ParseStatement(CHECK_OK); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 ParseExpression(true, CHECK_OK); | 654 ParseExpression(true, CHECK_OK); |
| 655 Expect(i::Token::RPAREN, CHECK_OK); | 655 Expect(i::Token::RPAREN, CHECK_OK); |
| 656 ParseStatement(ok); | 656 ParseStatement(ok); |
| 657 return Statement::Default(); | 657 return Statement::Default(); |
| 658 } | 658 } |
| 659 | 659 |
| 660 | 660 |
| 661 bool PreParser::CheckInOrOf(bool accept_OF) { | 661 bool PreParser::CheckInOrOf(bool accept_OF) { |
| 662 if (peek() == i::Token::IN || | 662 if (peek() == i::Token::IN || |
| 663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && | 663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && |
| 664 scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { | 664 scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { |
| 665 Next(); | 665 Next(); |
| 666 return true; | 666 return true; |
| 667 } | 667 } |
| 668 return false; | 668 return false; |
| 669 } | 669 } |
| 670 | 670 |
| 671 | 671 |
| 672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 673 // ForStatement :: | 673 // ForStatement :: |
| 674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 ParseStatement(ok); | 721 ParseStatement(ok); |
| 722 return Statement::Default(); | 722 return Statement::Default(); |
| 723 } | 723 } |
| 724 | 724 |
| 725 | 725 |
| 726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { | 726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
| 727 // ThrowStatement :: | 727 // ThrowStatement :: |
| 728 // 'throw' [no line terminator] Expression ';' | 728 // 'throw' [no line terminator] Expression ';' |
| 729 | 729 |
| 730 Expect(i::Token::THROW, CHECK_OK); | 730 Expect(i::Token::THROW, CHECK_OK); |
| 731 if (scanner_->HasAnyLineTerminatorBeforeNext()) { | 731 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 732 i::Scanner::Location pos = scanner_->location(); | 732 i::Scanner::Location pos = scanner()->location(); |
| 733 ReportMessageAt(pos, "newline_after_throw", NULL); | 733 ReportMessageAt(pos, "newline_after_throw", NULL); |
| 734 *ok = false; | 734 *ok = false; |
| 735 return Statement::Default(); | 735 return Statement::Default(); |
| 736 } | 736 } |
| 737 ParseExpression(true, CHECK_OK); | 737 ParseExpression(true, CHECK_OK); |
| 738 ExpectSemicolon(ok); | 738 ExpectSemicolon(ok); |
| 739 return Statement::Default(); | 739 return Statement::Default(); |
| 740 } | 740 } |
| 741 | 741 |
| 742 | 742 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 758 Expect(i::Token::TRY, CHECK_OK); | 758 Expect(i::Token::TRY, CHECK_OK); |
| 759 | 759 |
| 760 ParseBlock(CHECK_OK); | 760 ParseBlock(CHECK_OK); |
| 761 | 761 |
| 762 bool catch_or_finally_seen = false; | 762 bool catch_or_finally_seen = false; |
| 763 if (peek() == i::Token::CATCH) { | 763 if (peek() == i::Token::CATCH) { |
| 764 Consume(i::Token::CATCH); | 764 Consume(i::Token::CATCH); |
| 765 Expect(i::Token::LPAREN, CHECK_OK); | 765 Expect(i::Token::LPAREN, CHECK_OK); |
| 766 Identifier id = ParseIdentifier(CHECK_OK); | 766 Identifier id = ParseIdentifier(CHECK_OK); |
| 767 if (!is_classic_mode() && !id.IsValidStrictVariable()) { | 767 if (!is_classic_mode() && !id.IsValidStrictVariable()) { |
| 768 StrictModeIdentifierViolation(scanner_->location(), | 768 StrictModeIdentifierViolation(scanner()->location(), |
| 769 "strict_catch_variable", | 769 "strict_catch_variable", |
| 770 id, | 770 id, |
| 771 ok); | 771 ok); |
| 772 return Statement::Default(); | 772 return Statement::Default(); |
| 773 } | 773 } |
| 774 Expect(i::Token::RPAREN, CHECK_OK); | 774 Expect(i::Token::RPAREN, CHECK_OK); |
| 775 { Scope::InsideWith iw(scope_); | 775 { Scope::InsideWith iw(scope_); |
| 776 ParseBlock(CHECK_OK); | 776 ParseBlock(CHECK_OK); |
| 777 } | 777 } |
| 778 catch_or_finally_seen = true; | 778 catch_or_finally_seen = true; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 bool* ok) { | 831 bool* ok) { |
| 832 // AssignmentExpression :: | 832 // AssignmentExpression :: |
| 833 // ConditionalExpression | 833 // ConditionalExpression |
| 834 // YieldExpression | 834 // YieldExpression |
| 835 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 835 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 836 | 836 |
| 837 if (scope_->is_generator() && peek() == i::Token::YIELD) { | 837 if (scope_->is_generator() && peek() == i::Token::YIELD) { |
| 838 return ParseYieldExpression(ok); | 838 return ParseYieldExpression(ok); |
| 839 } | 839 } |
| 840 | 840 |
| 841 i::Scanner::Location before = scanner_->peek_location(); | 841 i::Scanner::Location before = scanner()->peek_location(); |
| 842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
| 843 | 843 |
| 844 if (!i::Token::IsAssignmentOp(peek())) { | 844 if (!i::Token::IsAssignmentOp(peek())) { |
| 845 // Parsed conditional expression only (no assignment). | 845 // Parsed conditional expression only (no assignment). |
| 846 return expression; | 846 return expression; |
| 847 } | 847 } |
| 848 | 848 |
| 849 if (!is_classic_mode() && | 849 if (!is_classic_mode() && |
| 850 expression.IsIdentifier() && | 850 expression.IsIdentifier() && |
| 851 expression.AsIdentifier().IsEvalOrArguments()) { | 851 expression.AsIdentifier().IsEvalOrArguments()) { |
| 852 i::Scanner::Location after = scanner_->location(); | 852 i::Scanner::Location after = scanner()->location(); |
| 853 ReportMessageAt(before.beg_pos, after.end_pos, | 853 ReportMessageAt(before.beg_pos, after.end_pos, |
| 854 "strict_lhs_assignment", NULL); | 854 "strict_lhs_assignment", NULL); |
| 855 *ok = false; | 855 *ok = false; |
| 856 return Expression::Default(); | 856 return Expression::Default(); |
| 857 } | 857 } |
| 858 | 858 |
| 859 i::Token::Value op = Next(); // Get assignment operator. | 859 i::Token::Value op = Next(); // Get assignment operator. |
| 860 ParseAssignmentExpression(accept_IN, CHECK_OK); | 860 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 861 | 861 |
| 862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { | 862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 // '~' UnaryExpression | 939 // '~' UnaryExpression |
| 940 // '!' UnaryExpression | 940 // '!' UnaryExpression |
| 941 | 941 |
| 942 i::Token::Value op = peek(); | 942 i::Token::Value op = peek(); |
| 943 if (i::Token::IsUnaryOp(op)) { | 943 if (i::Token::IsUnaryOp(op)) { |
| 944 op = Next(); | 944 op = Next(); |
| 945 ParseUnaryExpression(ok); | 945 ParseUnaryExpression(ok); |
| 946 return Expression::Default(); | 946 return Expression::Default(); |
| 947 } else if (i::Token::IsCountOp(op)) { | 947 } else if (i::Token::IsCountOp(op)) { |
| 948 op = Next(); | 948 op = Next(); |
| 949 i::Scanner::Location before = scanner_->peek_location(); | 949 i::Scanner::Location before = scanner()->peek_location(); |
| 950 Expression expression = ParseUnaryExpression(CHECK_OK); | 950 Expression expression = ParseUnaryExpression(CHECK_OK); |
| 951 if (!is_classic_mode() && | 951 if (!is_classic_mode() && |
| 952 expression.IsIdentifier() && | 952 expression.IsIdentifier() && |
| 953 expression.AsIdentifier().IsEvalOrArguments()) { | 953 expression.AsIdentifier().IsEvalOrArguments()) { |
| 954 i::Scanner::Location after = scanner_->location(); | 954 i::Scanner::Location after = scanner()->location(); |
| 955 ReportMessageAt(before.beg_pos, after.end_pos, | 955 ReportMessageAt(before.beg_pos, after.end_pos, |
| 956 "strict_lhs_prefix", NULL); | 956 "strict_lhs_prefix", NULL); |
| 957 *ok = false; | 957 *ok = false; |
| 958 } | 958 } |
| 959 return Expression::Default(); | 959 return Expression::Default(); |
| 960 } else { | 960 } else { |
| 961 return ParsePostfixExpression(ok); | 961 return ParsePostfixExpression(ok); |
| 962 } | 962 } |
| 963 } | 963 } |
| 964 | 964 |
| 965 | 965 |
| 966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { | 966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
| 967 // PostfixExpression :: | 967 // PostfixExpression :: |
| 968 // LeftHandSideExpression ('++' | '--')? | 968 // LeftHandSideExpression ('++' | '--')? |
| 969 | 969 |
| 970 i::Scanner::Location before = scanner_->peek_location(); | 970 i::Scanner::Location before = scanner()->peek_location(); |
| 971 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 971 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
| 972 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 972 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 973 i::Token::IsCountOp(peek())) { | 973 i::Token::IsCountOp(peek())) { |
| 974 if (!is_classic_mode() && | 974 if (!is_classic_mode() && |
| 975 expression.IsIdentifier() && | 975 expression.IsIdentifier() && |
| 976 expression.AsIdentifier().IsEvalOrArguments()) { | 976 expression.AsIdentifier().IsEvalOrArguments()) { |
| 977 i::Scanner::Location after = scanner_->location(); | 977 i::Scanner::Location after = scanner()->location(); |
| 978 ReportMessageAt(before.beg_pos, after.end_pos, | 978 ReportMessageAt(before.beg_pos, after.end_pos, |
| 979 "strict_lhs_postfix", NULL); | 979 "strict_lhs_postfix", NULL); |
| 980 *ok = false; | 980 *ok = false; |
| 981 return Expression::Default(); | 981 return Expression::Default(); |
| 982 } | 982 } |
| 983 Next(); | 983 Next(); |
| 984 return Expression::Default(); | 984 return Expression::Default(); |
| 985 } | 985 } |
| 986 return expression; | 986 return expression; |
| 987 } | 987 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 unsigned new_count, bool* ok) { | 1067 unsigned new_count, bool* ok) { |
| 1068 // MemberExpression :: | 1068 // MemberExpression :: |
| 1069 // (PrimaryExpression | FunctionLiteral) | 1069 // (PrimaryExpression | FunctionLiteral) |
| 1070 // ('[' Expression ']' | '.' Identifier | Arguments)* | 1070 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 1071 | 1071 |
| 1072 // Parse the initial primary or function expression. | 1072 // Parse the initial primary or function expression. |
| 1073 Expression result = Expression::Default(); | 1073 Expression result = Expression::Default(); |
| 1074 if (peek() == i::Token::FUNCTION) { | 1074 if (peek() == i::Token::FUNCTION) { |
| 1075 Consume(i::Token::FUNCTION); | 1075 Consume(i::Token::FUNCTION); |
| 1076 | 1076 |
| 1077 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 1077 bool is_generator = allow_generators() && Check(i::Token::MUL); |
| 1078 Identifier identifier = Identifier::Default(); | 1078 Identifier identifier = Identifier::Default(); |
| 1079 if (peek_any_identifier()) { | 1079 if (peek_any_identifier()) { |
| 1080 identifier = ParseIdentifier(CHECK_OK); | 1080 identifier = ParseIdentifier(CHECK_OK); |
| 1081 } | 1081 } |
| 1082 result = ParseFunctionLiteral(is_generator, CHECK_OK); | 1082 result = ParseFunctionLiteral(is_generator, CHECK_OK); |
| 1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { | 1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { |
| 1084 StrictModeIdentifierViolation(scanner_->location(), | 1084 StrictModeIdentifierViolation(scanner()->location(), |
| 1085 "strict_function_name", | 1085 "strict_function_name", |
| 1086 identifier, | 1086 identifier, |
| 1087 ok); | 1087 ok); |
| 1088 return Expression::Default(); | 1088 return Expression::Default(); |
| 1089 } | 1089 } |
| 1090 } else { | 1090 } else { |
| 1091 result = ParsePrimaryExpression(CHECK_OK); | 1091 result = ParsePrimaryExpression(CHECK_OK); |
| 1092 } | 1092 } |
| 1093 | 1093 |
| 1094 while (true) { | 1094 while (true) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 } | 1231 } |
| 1232 | 1232 |
| 1233 | 1233 |
| 1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
| 1235 // ObjectLiteral :: | 1235 // ObjectLiteral :: |
| 1236 // '{' ( | 1236 // '{' ( |
| 1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 1239 // )*[','] '}' | 1239 // )*[','] '}' |
| 1240 | 1240 |
| 1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); | 1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode()); |
| 1242 | 1242 |
| 1243 Expect(i::Token::LBRACE, CHECK_OK); | 1243 Expect(i::Token::LBRACE, CHECK_OK); |
| 1244 while (peek() != i::Token::RBRACE) { | 1244 while (peek() != i::Token::RBRACE) { |
| 1245 i::Token::Value next = peek(); | 1245 i::Token::Value next = peek(); |
| 1246 switch (next) { | 1246 switch (next) { |
| 1247 case i::Token::IDENTIFIER: | 1247 case i::Token::IDENTIFIER: |
| 1248 case i::Token::FUTURE_RESERVED_WORD: | 1248 case i::Token::FUTURE_RESERVED_WORD: |
| 1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1250 bool is_getter = false; | 1250 bool is_getter = false; |
| 1251 bool is_setter = false; | 1251 bool is_setter = false; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 } | 1305 } |
| 1306 Expect(i::Token::RBRACE, CHECK_OK); | 1306 Expect(i::Token::RBRACE, CHECK_OK); |
| 1307 | 1307 |
| 1308 scope_->NextMaterializedLiteralIndex(); | 1308 scope_->NextMaterializedLiteralIndex(); |
| 1309 return Expression::Default(); | 1309 return Expression::Default(); |
| 1310 } | 1310 } |
| 1311 | 1311 |
| 1312 | 1312 |
| 1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, | 1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, |
| 1314 bool* ok) { | 1314 bool* ok) { |
| 1315 if (!scanner_->ScanRegExpPattern(seen_equal)) { | 1315 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| 1316 Next(); | 1316 Next(); |
| 1317 ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL); | 1317 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL); |
| 1318 *ok = false; | 1318 *ok = false; |
| 1319 return Expression::Default(); | 1319 return Expression::Default(); |
| 1320 } | 1320 } |
| 1321 | 1321 |
| 1322 scope_->NextMaterializedLiteralIndex(); | 1322 scope_->NextMaterializedLiteralIndex(); |
| 1323 | 1323 |
| 1324 if (!scanner_->ScanRegExpFlags()) { | 1324 if (!scanner()->ScanRegExpFlags()) { |
| 1325 Next(); | 1325 Next(); |
| 1326 ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL); | 1326 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL); |
| 1327 *ok = false; | 1327 *ok = false; |
| 1328 return Expression::Default(); | 1328 return Expression::Default(); |
| 1329 } | 1329 } |
| 1330 Next(); | 1330 Next(); |
| 1331 return Expression::Default(); | 1331 return Expression::Default(); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) { | 1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) { |
| 1336 // Arguments :: | 1336 // Arguments :: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 1362 | 1362 |
| 1363 // Parse function body. | 1363 // Parse function body. |
| 1364 ScopeType outer_scope_type = scope_->type(); | 1364 ScopeType outer_scope_type = scope_->type(); |
| 1365 bool inside_with = scope_->IsInsideWith(); | 1365 bool inside_with = scope_->IsInsideWith(); |
| 1366 Scope function_scope(&scope_, kFunctionScope); | 1366 Scope function_scope(&scope_, kFunctionScope); |
| 1367 function_scope.set_is_generator(is_generator); | 1367 function_scope.set_is_generator(is_generator); |
| 1368 // FormalParameterList :: | 1368 // FormalParameterList :: |
| 1369 // '(' (Identifier)*[','] ')' | 1369 // '(' (Identifier)*[','] ')' |
| 1370 Expect(i::Token::LPAREN, CHECK_OK); | 1370 Expect(i::Token::LPAREN, CHECK_OK); |
| 1371 int start_position = scanner_->location().beg_pos; | 1371 int start_position = scanner()->location().beg_pos; |
| 1372 bool done = (peek() == i::Token::RPAREN); | 1372 bool done = (peek() == i::Token::RPAREN); |
| 1373 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | 1373 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 1374 while (!done) { | 1374 while (!done) { |
| 1375 Identifier id = ParseIdentifier(CHECK_OK); | 1375 Identifier id = ParseIdentifier(CHECK_OK); |
| 1376 if (!id.IsValidStrictVariable()) { | 1376 if (!id.IsValidStrictVariable()) { |
| 1377 StrictModeIdentifierViolation(scanner_->location(), | 1377 StrictModeIdentifierViolation(scanner()->location(), |
| 1378 "strict_param_name", | 1378 "strict_param_name", |
| 1379 id, | 1379 id, |
| 1380 CHECK_OK); | 1380 CHECK_OK); |
| 1381 } | 1381 } |
| 1382 int prev_value; | 1382 int prev_value; |
| 1383 if (scanner_->is_literal_ascii()) { | 1383 if (scanner()->is_literal_ascii()) { |
| 1384 prev_value = | 1384 prev_value = |
| 1385 duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1); | 1385 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); |
| 1386 } else { | 1386 } else { |
| 1387 prev_value = | 1387 prev_value = |
| 1388 duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1); | 1388 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); |
| 1389 } | 1389 } |
| 1390 | 1390 |
| 1391 if (prev_value != 0) { | 1391 if (prev_value != 0) { |
| 1392 SetStrictModeViolation(scanner_->location(), | 1392 SetStrictModeViolation(scanner()->location(), |
| 1393 "strict_param_dupe", | 1393 "strict_param_dupe", |
| 1394 CHECK_OK); | 1394 CHECK_OK); |
| 1395 } | 1395 } |
| 1396 done = (peek() == i::Token::RPAREN); | 1396 done = (peek() == i::Token::RPAREN); |
| 1397 if (!done) { | 1397 if (!done) { |
| 1398 Expect(i::Token::COMMA, CHECK_OK); | 1398 Expect(i::Token::COMMA, CHECK_OK); |
| 1399 } | 1399 } |
| 1400 } | 1400 } |
| 1401 Expect(i::Token::RPAREN, CHECK_OK); | 1401 Expect(i::Token::RPAREN, CHECK_OK); |
| 1402 | 1402 |
| 1403 // Determine if the function will be lazily compiled. | 1403 // Determine if the function will be lazily compiled. |
| 1404 // Currently only happens to top-level functions. | 1404 // Currently only happens to top-level functions. |
| 1405 // Optimistically assume that all top-level functions are lazily compiled. | 1405 // Optimistically assume that all top-level functions are lazily compiled. |
| 1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && | 1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && |
| 1407 !inside_with && allow_lazy_ && | 1407 !inside_with && allow_lazy() && |
| 1408 !parenthesized_function_); | 1408 !parenthesized_function_); |
| 1409 parenthesized_function_ = false; | 1409 parenthesized_function_ = false; |
| 1410 | 1410 |
| 1411 Expect(i::Token::LBRACE, CHECK_OK); | 1411 Expect(i::Token::LBRACE, CHECK_OK); |
| 1412 if (is_lazily_compiled) { | 1412 if (is_lazily_compiled) { |
| 1413 ParseLazyFunctionLiteralBody(CHECK_OK); | 1413 ParseLazyFunctionLiteralBody(CHECK_OK); |
| 1414 } else { | 1414 } else { |
| 1415 ParseSourceElements(i::Token::RBRACE, ok); | 1415 ParseSourceElements(i::Token::RBRACE, ok); |
| 1416 } | 1416 } |
| 1417 Expect(i::Token::RBRACE, CHECK_OK); | 1417 Expect(i::Token::RBRACE, CHECK_OK); |
| 1418 | 1418 |
| 1419 if (!is_classic_mode()) { | 1419 if (!is_classic_mode()) { |
| 1420 int end_position = scanner_->location().end_pos; | 1420 int end_position = scanner()->location().end_pos; |
| 1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); | 1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
| 1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); | 1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); |
| 1423 return Expression::StrictFunction(); | 1423 return Expression::StrictFunction(); |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 return Expression::Default(); | 1426 return Expression::Default(); |
| 1427 } | 1427 } |
| 1428 | 1428 |
| 1429 | 1429 |
| 1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
| 1431 int body_start = scanner_->location().beg_pos; | 1431 int body_start = scanner()->location().beg_pos; |
| 1432 log_->PauseRecording(); | 1432 log_->PauseRecording(); |
| 1433 ParseSourceElements(i::Token::RBRACE, ok); | 1433 ParseSourceElements(i::Token::RBRACE, ok); |
| 1434 log_->ResumeRecording(); | 1434 log_->ResumeRecording(); |
| 1435 if (!*ok) return; | 1435 if (!*ok) return; |
| 1436 | 1436 |
| 1437 // Position right after terminal '}'. | 1437 // Position right after terminal '}'. |
| 1438 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 1438 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
| 1439 int body_end = scanner_->peek_location().end_pos; | 1439 int body_end = scanner()->peek_location().end_pos; |
| 1440 log_->LogFunction(body_start, body_end, | 1440 log_->LogFunction(body_start, body_end, |
| 1441 scope_->materialized_literal_count(), | 1441 scope_->materialized_literal_count(), |
| 1442 scope_->expected_properties(), | 1442 scope_->expected_properties(), |
| 1443 language_mode()); | 1443 language_mode()); |
| 1444 } | 1444 } |
| 1445 | 1445 |
| 1446 | 1446 |
| 1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
| 1448 // CallRuntime :: | 1448 // CallRuntime :: |
| 1449 // '%' Identifier Arguments | 1449 // '%' Identifier Arguments |
| 1450 Expect(i::Token::MOD, CHECK_OK); | 1450 Expect(i::Token::MOD, CHECK_OK); |
| 1451 if (!allow_natives_syntax_) { | 1451 if (!allow_natives_syntax()) { |
| 1452 *ok = false; | 1452 *ok = false; |
| 1453 return Expression::Default(); | 1453 return Expression::Default(); |
| 1454 } | 1454 } |
| 1455 ParseIdentifier(CHECK_OK); | 1455 ParseIdentifier(CHECK_OK); |
| 1456 ParseArguments(ok); | 1456 ParseArguments(ok); |
| 1457 | 1457 |
| 1458 return Expression::Default(); | 1458 return Expression::Default(); |
| 1459 } | 1459 } |
| 1460 | 1460 |
| 1461 #undef CHECK_OK | 1461 #undef CHECK_OK |
| 1462 | 1462 |
| 1463 | 1463 |
| 1464 void PreParser::ExpectSemicolon(bool* ok) { | |
| 1465 // Check for automatic semicolon insertion according to | |
| 1466 // the rules given in ECMA-262, section 7.9, page 21. | |
| 1467 i::Token::Value tok = peek(); | |
| 1468 if (tok == i::Token::SEMICOLON) { | |
| 1469 Next(); | |
| 1470 return; | |
| 1471 } | |
| 1472 if (scanner_->HasAnyLineTerminatorBeforeNext() || | |
| 1473 tok == i::Token::RBRACE || | |
| 1474 tok == i::Token::EOS) { | |
| 1475 return; | |
| 1476 } | |
| 1477 Expect(i::Token::SEMICOLON, ok); | |
| 1478 } | |
| 1479 | |
| 1480 | |
| 1481 void PreParser::LogSymbol() { | 1464 void PreParser::LogSymbol() { |
| 1482 int identifier_pos = scanner_->location().beg_pos; | 1465 int identifier_pos = scanner()->location().beg_pos; |
| 1483 if (scanner_->is_literal_ascii()) { | 1466 if (scanner()->is_literal_ascii()) { |
| 1484 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); | 1467 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); |
| 1485 } else { | 1468 } else { |
| 1486 log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string()); | 1469 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); |
| 1487 } | 1470 } |
| 1488 } | 1471 } |
| 1489 | 1472 |
| 1490 | 1473 |
| 1491 PreParser::Expression PreParser::GetStringSymbol() { | 1474 PreParser::Expression PreParser::GetStringSymbol() { |
| 1492 const int kUseStrictLength = 10; | 1475 const int kUseStrictLength = 10; |
| 1493 const char* kUseStrictChars = "use strict"; | 1476 const char* kUseStrictChars = "use strict"; |
| 1494 LogSymbol(); | 1477 LogSymbol(); |
| 1495 if (scanner_->is_literal_ascii() && | 1478 if (scanner()->is_literal_ascii() && |
| 1496 scanner_->literal_length() == kUseStrictLength && | 1479 scanner()->literal_length() == kUseStrictLength && |
| 1497 !scanner_->literal_contains_escapes() && | 1480 !scanner()->literal_contains_escapes() && |
| 1498 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, | 1481 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars, |
| 1499 kUseStrictLength)) { | 1482 kUseStrictLength)) { |
| 1500 return Expression::UseStrictStringLiteral(); | 1483 return Expression::UseStrictStringLiteral(); |
| 1501 } | 1484 } |
| 1502 return Expression::StringLiteral(); | 1485 return Expression::StringLiteral(); |
| 1503 } | 1486 } |
| 1504 | 1487 |
| 1505 | 1488 |
| 1506 PreParser::Identifier PreParser::GetIdentifierSymbol() { | 1489 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
| 1507 LogSymbol(); | 1490 LogSymbol(); |
| 1508 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { | 1491 if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) { |
| 1509 return Identifier::FutureReserved(); | 1492 return Identifier::FutureReserved(); |
| 1510 } else if (scanner_->current_token() == | 1493 } else if (scanner()->current_token() == |
| 1511 i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1494 i::Token::FUTURE_STRICT_RESERVED_WORD) { |
| 1512 return Identifier::FutureStrictReserved(); | 1495 return Identifier::FutureStrictReserved(); |
| 1513 } else if (scanner_->current_token() == i::Token::YIELD) { | 1496 } else if (scanner()->current_token() == i::Token::YIELD) { |
| 1514 return Identifier::Yield(); | 1497 return Identifier::Yield(); |
| 1515 } | 1498 } |
| 1516 if (scanner_->is_literal_ascii()) { | 1499 if (scanner()->is_literal_ascii()) { |
| 1517 // Detect strict-mode poison words. | 1500 // Detect strict-mode poison words. |
| 1518 if (scanner_->literal_length() == 4 && | 1501 if (scanner()->literal_length() == 4 && |
| 1519 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { | 1502 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) { |
| 1520 return Identifier::Eval(); | 1503 return Identifier::Eval(); |
| 1521 } | 1504 } |
| 1522 if (scanner_->literal_length() == 9 && | 1505 if (scanner()->literal_length() == 9 && |
| 1523 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { | 1506 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { |
| 1524 return Identifier::Arguments(); | 1507 return Identifier::Arguments(); |
| 1525 } | 1508 } |
| 1526 } | 1509 } |
| 1527 return Identifier::Default(); | 1510 return Identifier::Default(); |
| 1528 } | 1511 } |
| 1529 | 1512 |
| 1530 | 1513 |
| 1531 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1514 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
| 1532 i::Token::Value next = Next(); | 1515 i::Token::Value next = Next(); |
| 1533 switch (next) { | 1516 switch (next) { |
| 1534 case i::Token::FUTURE_RESERVED_WORD: { | 1517 case i::Token::FUTURE_RESERVED_WORD: { |
| 1535 i::Scanner::Location location = scanner_->location(); | 1518 i::Scanner::Location location = scanner()->location(); |
| 1536 ReportMessageAt(location.beg_pos, location.end_pos, | 1519 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1537 "reserved_word", NULL); | 1520 "reserved_word", NULL); |
| 1538 *ok = false; | 1521 *ok = false; |
| 1539 return GetIdentifierSymbol(); | 1522 return GetIdentifierSymbol(); |
| 1540 } | 1523 } |
| 1541 case i::Token::YIELD: | 1524 case i::Token::YIELD: |
| 1542 if (scope_->is_generator()) { | 1525 if (scope_->is_generator()) { |
| 1543 // 'yield' in a generator is only valid as part of a YieldExpression. | 1526 // 'yield' in a generator is only valid as part of a YieldExpression. |
| 1544 ReportMessageAt(scanner_->location(), "unexpected_token", "yield"); | 1527 ReportMessageAt(scanner()->location(), "unexpected_token", "yield"); |
| 1545 *ok = false; | 1528 *ok = false; |
| 1546 return Identifier::Yield(); | 1529 return Identifier::Yield(); |
| 1547 } | 1530 } |
| 1548 // FALLTHROUGH | 1531 // FALLTHROUGH |
| 1549 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 1532 case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| 1550 if (!is_classic_mode()) { | 1533 if (!is_classic_mode()) { |
| 1551 i::Scanner::Location location = scanner_->location(); | 1534 i::Scanner::Location location = scanner()->location(); |
| 1552 ReportMessageAt(location.beg_pos, location.end_pos, | 1535 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1553 "strict_reserved_word", NULL); | 1536 "strict_reserved_word", NULL); |
| 1554 *ok = false; | 1537 *ok = false; |
| 1555 } | 1538 } |
| 1556 // FALLTHROUGH | 1539 // FALLTHROUGH |
| 1557 case i::Token::IDENTIFIER: | 1540 case i::Token::IDENTIFIER: |
| 1558 return GetIdentifierSymbol(); | 1541 return GetIdentifierSymbol(); |
| 1559 default: | 1542 default: |
| 1560 *ok = false; | 1543 *ok = false; |
| 1561 return Identifier::Default(); | 1544 return Identifier::Default(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1612 return; | 1595 return; |
| 1613 } | 1596 } |
| 1614 strict_mode_violation_location_ = location; | 1597 strict_mode_violation_location_ = location; |
| 1615 strict_mode_violation_type_ = type; | 1598 strict_mode_violation_type_ = type; |
| 1616 } | 1599 } |
| 1617 | 1600 |
| 1618 | 1601 |
| 1619 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { | 1602 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
| 1620 i::Token::Value next = Next(); | 1603 i::Token::Value next = Next(); |
| 1621 if (i::Token::IsKeyword(next)) { | 1604 if (i::Token::IsKeyword(next)) { |
| 1622 int pos = scanner_->location().beg_pos; | 1605 int pos = scanner()->location().beg_pos; |
| 1623 const char* keyword = i::Token::String(next); | 1606 const char* keyword = i::Token::String(next); |
| 1624 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, | 1607 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, |
| 1625 i::StrLength(keyword))); | 1608 i::StrLength(keyword))); |
| 1626 return Identifier::Default(); | 1609 return Identifier::Default(); |
| 1627 } | 1610 } |
| 1628 if (next == i::Token::IDENTIFIER || | 1611 if (next == i::Token::IDENTIFIER || |
| 1629 next == i::Token::FUTURE_RESERVED_WORD || | 1612 next == i::Token::FUTURE_RESERVED_WORD || |
| 1630 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1613 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { |
| 1631 return GetIdentifierSymbol(); | 1614 return GetIdentifierSymbol(); |
| 1632 } | 1615 } |
| 1633 *ok = false; | 1616 *ok = false; |
| 1634 return Identifier::Default(); | 1617 return Identifier::Default(); |
| 1635 } | 1618 } |
| 1636 | 1619 |
| 1637 #undef CHECK_OK | 1620 #undef CHECK_OK |
| 1638 | 1621 |
| 1639 | 1622 |
| 1640 // This function reads an identifier and determines whether or not it | 1623 // This function reads an identifier and determines whether or not it |
| 1641 // is 'get' or 'set'. | 1624 // is 'get' or 'set'. |
| 1642 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 1625 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 1643 bool* is_set, | 1626 bool* is_set, |
| 1644 bool* ok) { | 1627 bool* ok) { |
| 1645 Identifier result = ParseIdentifierName(ok); | 1628 Identifier result = ParseIdentifierName(ok); |
| 1646 if (!*ok) return Identifier::Default(); | 1629 if (!*ok) return Identifier::Default(); |
| 1647 if (scanner_->is_literal_ascii() && | 1630 if (scanner()->is_literal_ascii() && |
| 1648 scanner_->literal_length() == 3) { | 1631 scanner()->literal_length() == 3) { |
| 1649 const char* token = scanner_->literal_ascii_string().start(); | 1632 const char* token = scanner()->literal_ascii_string().start(); |
| 1650 *is_get = strncmp(token, "get", 3) == 0; | 1633 *is_get = strncmp(token, "get", 3) == 0; |
| 1651 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1634 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 1652 } | 1635 } |
| 1653 return result; | 1636 return result; |
| 1654 } | 1637 } |
| 1655 | 1638 |
| 1656 | 1639 |
| 1657 bool PreParser::peek_any_identifier() { | |
| 1658 i::Token::Value next = peek(); | |
| 1659 return next == i::Token::IDENTIFIER || | |
| 1660 next == i::Token::FUTURE_RESERVED_WORD || | |
| 1661 next == i::Token::FUTURE_STRICT_RESERVED_WORD || | |
| 1662 next == i::Token::YIELD; | |
| 1663 } | |
| 1664 | |
| 1665 } } // v8::internal | 1640 } } // v8::internal |
| OLD | NEW |