| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 28 matching lines...) Expand all Loading... |
| 39 #include "platform.h" | 39 #include "platform.h" |
| 40 #include "preparser.h" | 40 #include "preparser.h" |
| 41 #include "runtime.h" | 41 #include "runtime.h" |
| 42 #include "scanner-character-streams.h" | 42 #include "scanner-character-streams.h" |
| 43 #include "scopeinfo.h" | 43 #include "scopeinfo.h" |
| 44 #include "string-stream.h" | 44 #include "string-stream.h" |
| 45 | 45 |
| 46 namespace v8 { | 46 namespace v8 { |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 // PositionStack is used for on-stack allocation of token positions for | |
| 50 // new expressions. Please look at ParseNewExpression. | |
| 51 | |
| 52 class PositionStack { | |
| 53 public: | |
| 54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} | |
| 55 ~PositionStack() { | |
| 56 ASSERT(!*ok_ || is_empty()); | |
| 57 USE(ok_); | |
| 58 } | |
| 59 | |
| 60 class Element { | |
| 61 public: | |
| 62 Element(PositionStack* stack, int value) { | |
| 63 previous_ = stack->top(); | |
| 64 value_ = value; | |
| 65 stack->set_top(this); | |
| 66 } | |
| 67 | |
| 68 private: | |
| 69 Element* previous() { return previous_; } | |
| 70 int value() { return value_; } | |
| 71 friend class PositionStack; | |
| 72 Element* previous_; | |
| 73 int value_; | |
| 74 }; | |
| 75 | |
| 76 bool is_empty() { return top_ == NULL; } | |
| 77 int pop() { | |
| 78 ASSERT(!is_empty()); | |
| 79 int result = top_->value(); | |
| 80 top_ = top_->previous(); | |
| 81 return result; | |
| 82 } | |
| 83 | |
| 84 private: | |
| 85 Element* top() { return top_; } | |
| 86 void set_top(Element* value) { top_ = value; } | |
| 87 Element* top_; | |
| 88 bool* ok_; | |
| 89 }; | |
| 90 | |
| 91 | |
| 92 RegExpBuilder::RegExpBuilder(Zone* zone) | 49 RegExpBuilder::RegExpBuilder(Zone* zone) |
| 93 : zone_(zone), | 50 : zone_(zone), |
| 94 pending_empty_(false), | 51 pending_empty_(false), |
| 95 characters_(NULL), | 52 characters_(NULL), |
| 96 terms_(), | 53 terms_(), |
| 97 alternatives_() | 54 alternatives_() |
| 98 #ifdef DEBUG | 55 #ifdef DEBUG |
| 99 , last_added_(ADD_NONE) | 56 , last_added_(ADD_NONE) |
| 100 #endif | 57 #endif |
| 101 {} | 58 {} |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 UNREACHABLE(); | 200 UNREACHABLE(); |
| 244 return; | 201 return; |
| 245 } | 202 } |
| 246 terms_.Add( | 203 terms_.Add( |
| 247 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); | 204 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); |
| 248 LAST(ADD_TERM); | 205 LAST(ADD_TERM); |
| 249 } | 206 } |
| 250 | 207 |
| 251 | 208 |
| 252 Handle<String> Parser::LookupSymbol(int symbol_id) { | 209 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 253 // Length of symbol cache is the number of identified symbols. | 210 // If there is no preparser symbol data, a negative number will be passed. In |
| 254 // If we are larger than that, or negative, it's not a cached symbol. | 211 // that case, we'll just read the literal from Scanner. This also guards |
| 255 // This might also happen if there is no preparser symbol data, even | 212 // against corrupt preparse data where the symbol id is larger than the symbol |
| 256 // if there is some preparser data. | 213 // count. |
| 257 if (static_cast<unsigned>(symbol_id) | 214 if (symbol_id < 0 || |
| 258 >= static_cast<unsigned>(symbol_cache_.length())) { | 215 (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) { |
| 259 return scanner().GetLiteralSymbol(); | 216 if (scanner()->is_literal_ascii()) { |
| 217 return isolate()->factory()->InternalizeOneByteString( |
| 218 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); |
| 219 } else { |
| 220 return isolate()->factory()->InternalizeTwoByteString( |
| 221 scanner()->literal_utf16_string()); |
| 222 } |
| 260 } | 223 } |
| 261 return LookupCachedSymbol(symbol_id); | 224 return LookupCachedSymbol(symbol_id); |
| 262 } | 225 } |
| 263 | 226 |
| 264 | 227 |
| 265 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { | 228 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { |
| 266 // Make sure the cache is large enough to hold the symbol identifier. | 229 // Make sure the cache is large enough to hold the symbol identifier. |
| 267 if (symbol_cache_.length() <= symbol_id) { | 230 if (symbol_cache_.length() <= symbol_id) { |
| 268 // Increase length to index + 1. | 231 // Increase length to index + 1. |
| 269 symbol_cache_.AddBlock(Handle<String>::null(), | 232 symbol_cache_.AddBlock(Handle<String>::null(), |
| 270 symbol_id + 1 - symbol_cache_.length(), zone()); | 233 symbol_id + 1 - symbol_cache_.length(), zone()); |
| 271 } | 234 } |
| 272 Handle<String> result = symbol_cache_.at(symbol_id); | 235 Handle<String> result = symbol_cache_.at(symbol_id); |
| 273 if (result.is_null()) { | 236 if (result.is_null()) { |
| 274 result = scanner().GetLiteralSymbol(); | 237 if (scanner()->is_literal_ascii()) { |
| 238 result = isolate()->factory()->InternalizeOneByteString( |
| 239 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); |
| 240 } else { |
| 241 result = isolate()->factory()->InternalizeTwoByteString( |
| 242 scanner()->literal_utf16_string()); |
| 243 } |
| 275 symbol_cache_.at(symbol_id) = result; | 244 symbol_cache_.at(symbol_id) = result; |
| 276 return result; | 245 return result; |
| 277 } | 246 } |
| 278 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); | 247 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); |
| 279 return result; | 248 return result; |
| 280 } | 249 } |
| 281 | 250 |
| 282 | 251 |
| 283 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 252 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 284 // The current pre-data entry must be a FunctionEntry with the given | 253 // The current pre-data entry must be a FunctionEntry with the given |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 char* result = NewArray<char>(length + 1); | 322 char* result = NewArray<char>(length + 1); |
| 354 for (int i = 0; i < length; i++) { | 323 for (int i = 0; i < length; i++) { |
| 355 result[i] = start[i + 1]; | 324 result[i] = start[i + 1]; |
| 356 } | 325 } |
| 357 result[length] = '\0'; | 326 result[length] = '\0'; |
| 358 if (chars != NULL) *chars = length; | 327 if (chars != NULL) *chars = length; |
| 359 return result; | 328 return result; |
| 360 } | 329 } |
| 361 | 330 |
| 362 | 331 |
| 363 ScannerBase::Location ScriptDataImpl::MessageLocation() { | 332 Scanner::Location ScriptDataImpl::MessageLocation() { |
| 364 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); | 333 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); |
| 365 int end_pos = Read(PreparseDataConstants::kMessageEndPos); | 334 int end_pos = Read(PreparseDataConstants::kMessageEndPos); |
| 366 return ScannerBase::Location(beg_pos, end_pos); | 335 return Scanner::Location(beg_pos, end_pos); |
| 367 } | 336 } |
| 368 | 337 |
| 369 | 338 |
| 370 const char* ScriptDataImpl::BuildMessage() { | 339 const char* ScriptDataImpl::BuildMessage() { |
| 371 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); | 340 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); |
| 372 return ReadString(start, NULL); | 341 return ReadString(start, NULL); |
| 373 } | 342 } |
| 374 | 343 |
| 375 | 344 |
| 376 Vector<const char*> ScriptDataImpl::BuildArgs() { | 345 Vector<const char*> ScriptDataImpl::BuildArgs() { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 *variable_ = previous_; | 413 *variable_ = previous_; |
| 445 } | 414 } |
| 446 | 415 |
| 447 private: | 416 private: |
| 448 Target** variable_; | 417 Target** variable_; |
| 449 Target* previous_; | 418 Target* previous_; |
| 450 }; | 419 }; |
| 451 | 420 |
| 452 | 421 |
| 453 // ---------------------------------------------------------------------------- | 422 // ---------------------------------------------------------------------------- |
| 454 // FunctionState and BlockState together implement the parser's scope stack. | |
| 455 // The parser's current scope is in top_scope_. The BlockState and | |
| 456 // FunctionState constructors push on the scope stack and the destructors | |
| 457 // pop. They are also used to hold the parser's per-function and per-block | |
| 458 // state. | |
| 459 | |
| 460 class Parser::BlockState BASE_EMBEDDED { | |
| 461 public: | |
| 462 BlockState(Parser* parser, Scope* scope) | |
| 463 : parser_(parser), | |
| 464 outer_scope_(parser->top_scope_) { | |
| 465 parser->top_scope_ = scope; | |
| 466 } | |
| 467 | |
| 468 ~BlockState() { parser_->top_scope_ = outer_scope_; } | |
| 469 | |
| 470 private: | |
| 471 Parser* parser_; | |
| 472 Scope* outer_scope_; | |
| 473 }; | |
| 474 | |
| 475 | |
| 476 Parser::FunctionState::FunctionState(Parser* parser, | |
| 477 Scope* scope, | |
| 478 Isolate* isolate) | |
| 479 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
| 480 next_handler_index_(0), | |
| 481 expected_property_count_(0), | |
| 482 generator_object_variable_(NULL), | |
| 483 parser_(parser), | |
| 484 outer_function_state_(parser->current_function_state_), | |
| 485 outer_scope_(parser->top_scope_), | |
| 486 saved_ast_node_id_(isolate->ast_node_id()), | |
| 487 factory_(isolate, parser->zone()) { | |
| 488 parser->top_scope_ = scope; | |
| 489 parser->current_function_state_ = this; | |
| 490 isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt()); | |
| 491 } | |
| 492 | |
| 493 | |
| 494 Parser::FunctionState::~FunctionState() { | |
| 495 parser_->top_scope_ = outer_scope_; | |
| 496 parser_->current_function_state_ = outer_function_state_; | |
| 497 if (outer_function_state_ != NULL) { | |
| 498 parser_->isolate()->set_ast_node_id(saved_ast_node_id_); | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 | |
| 503 // ---------------------------------------------------------------------------- | |
| 504 // The CHECK_OK macro is a convenient macro to enforce error | 423 // The CHECK_OK macro is a convenient macro to enforce error |
| 505 // handling for functions that may fail (by returning !*ok). | 424 // handling for functions that may fail (by returning !*ok). |
| 506 // | 425 // |
| 507 // CAUTION: This macro appends extra statements after a call, | 426 // CAUTION: This macro appends extra statements after a call, |
| 508 // thus it must never be used where only a single statement | 427 // thus it must never be used where only a single statement |
| 509 // is correct (e.g. an if statement branch w/o braces)! | 428 // is correct (e.g. an if statement branch w/o braces)! |
| 510 | 429 |
| 511 #define CHECK_OK ok); \ | 430 #define CHECK_OK ok); \ |
| 512 if (!*ok) return NULL; \ | 431 if (!*ok) return NULL; \ |
| 513 ((void)0 | 432 ((void)0 |
| 514 #define DUMMY ) // to make indentation work | 433 #define DUMMY ) // to make indentation work |
| 515 #undef DUMMY | 434 #undef DUMMY |
| 516 | 435 |
| 517 #define CHECK_FAILED /**/); \ | 436 #define CHECK_FAILED /**/); \ |
| 518 if (failed_) return NULL; \ | 437 if (failed_) return NULL; \ |
| 519 ((void)0 | 438 ((void)0 |
| 520 #define DUMMY ) // to make indentation work | 439 #define DUMMY ) // to make indentation work |
| 521 #undef DUMMY | 440 #undef DUMMY |
| 522 | 441 |
| 523 // ---------------------------------------------------------------------------- | 442 // ---------------------------------------------------------------------------- |
| 524 // Implementation of Parser | 443 // Implementation of Parser |
| 525 | 444 |
| 445 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 446 return identifier.is_identical_to( |
| 447 parser_->isolate()->factory()->eval_string()) || |
| 448 identifier.is_identical_to( |
| 449 parser_->isolate()->factory()->arguments_string()); |
| 450 } |
| 451 |
| 452 |
| 453 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 454 const char* message, |
| 455 Vector<const char*> args) { |
| 456 MessageLocation location(parser_->script_, |
| 457 source_location.beg_pos, |
| 458 source_location.end_pos); |
| 459 Factory* factory = parser_->isolate()->factory(); |
| 460 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 461 for (int i = 0; i < args.length(); i++) { |
| 462 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| 463 elements->set(i, *arg_string); |
| 464 } |
| 465 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 466 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 467 parser_->isolate()->Throw(*result, &location); |
| 468 } |
| 469 |
| 470 |
| 471 void ParserTraits::ReportMessage(const char* message, |
| 472 Vector<Handle<String> > args) { |
| 473 Scanner::Location source_location = parser_->scanner()->location(); |
| 474 ReportMessageAt(source_location, message, args); |
| 475 } |
| 476 |
| 477 |
| 478 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 479 const char* message, |
| 480 Vector<Handle<String> > args) { |
| 481 MessageLocation location(parser_->script_, |
| 482 source_location.beg_pos, |
| 483 source_location.end_pos); |
| 484 Factory* factory = parser_->isolate()->factory(); |
| 485 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 486 for (int i = 0; i < args.length(); i++) { |
| 487 elements->set(i, *args[i]); |
| 488 } |
| 489 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 490 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 491 parser_->isolate()->Throw(*result, &location); |
| 492 } |
| 493 |
| 494 |
| 495 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
| 496 int symbol_id = -1; |
| 497 if (parser_->pre_parse_data() != NULL) { |
| 498 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); |
| 499 } |
| 500 return parser_->LookupSymbol(symbol_id); |
| 501 } |
| 502 |
| 503 |
| 504 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
| 505 PretenureFlag tenured) { |
| 506 if (scanner->is_next_literal_ascii()) { |
| 507 return parser_->isolate_->factory()->NewStringFromAscii( |
| 508 scanner->next_literal_ascii_string(), tenured); |
| 509 } else { |
| 510 return parser_->isolate_->factory()->NewStringFromTwoByte( |
| 511 scanner->next_literal_utf16_string(), tenured); |
| 512 } |
| 513 } |
| 514 |
| 515 |
| 516 Expression* ParserTraits::ThisExpression( |
| 517 Scope* scope, |
| 518 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 519 return factory->NewVariableProxy(scope->receiver()); |
| 520 } |
| 521 |
| 522 |
| 523 Expression* ParserTraits::ExpressionFromLiteral( |
| 524 Token::Value token, int pos, |
| 525 Scanner* scanner, |
| 526 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 527 Factory* isolate_factory = parser_->isolate()->factory(); |
| 528 switch (token) { |
| 529 case Token::NULL_LITERAL: |
| 530 return factory->NewLiteral(isolate_factory->null_value(), pos); |
| 531 case Token::TRUE_LITERAL: |
| 532 return factory->NewLiteral(isolate_factory->true_value(), pos); |
| 533 case Token::FALSE_LITERAL: |
| 534 return factory->NewLiteral(isolate_factory->false_value(), pos); |
| 535 case Token::NUMBER: { |
| 536 ASSERT(scanner->is_literal_ascii()); |
| 537 double value = StringToDouble(parser_->isolate()->unicode_cache(), |
| 538 scanner->literal_ascii_string(), |
| 539 ALLOW_HEX | ALLOW_OCTAL | |
| 540 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 541 return factory->NewNumberLiteral(value, pos); |
| 542 } |
| 543 default: |
| 544 ASSERT(false); |
| 545 } |
| 546 return NULL; |
| 547 } |
| 548 |
| 549 |
| 550 Expression* ParserTraits::ExpressionFromIdentifier( |
| 551 Handle<String> name, int pos, Scope* scope, |
| 552 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 553 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 554 // The name may refer to a module instance object, so its type is unknown. |
| 555 #ifdef DEBUG |
| 556 if (FLAG_print_interface_details) |
| 557 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 558 #endif |
| 559 Interface* interface = Interface::NewUnknown(parser_->zone()); |
| 560 return scope->NewUnresolved(factory, name, interface, pos); |
| 561 } |
| 562 |
| 563 |
| 564 Expression* ParserTraits::ExpressionFromString( |
| 565 int pos, Scanner* scanner, |
| 566 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 567 Handle<String> symbol = GetSymbol(scanner); |
| 568 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 569 return factory->NewLiteral(symbol, pos); |
| 570 } |
| 571 |
| 572 |
| 573 Literal* ParserTraits::GetLiteralTheHole( |
| 574 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 575 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| 576 RelocInfo::kNoPosition); |
| 577 } |
| 578 |
| 579 |
| 580 Expression* ParserTraits::ParseObjectLiteral(bool* ok) { |
| 581 return parser_->ParseObjectLiteral(ok); |
| 582 } |
| 583 |
| 584 |
| 585 Expression* ParserTraits::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 586 return parser_->ParseAssignmentExpression(accept_IN, ok); |
| 587 } |
| 588 |
| 589 |
| 590 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 591 return parser_->ParseV8Intrinsic(ok); |
| 592 } |
| 593 |
| 594 |
| 526 Parser::Parser(CompilationInfo* info) | 595 Parser::Parser(CompilationInfo* info) |
| 527 : ParserBase(NULL, info->isolate()->stack_guard()->real_climit()), | 596 : ParserBase<ParserTraits>(&scanner_, |
| 597 info->isolate()->stack_guard()->real_climit(), |
| 598 info->extension(), |
| 599 info->zone(), |
| 600 this), |
| 528 isolate_(info->isolate()), | 601 isolate_(info->isolate()), |
| 529 symbol_cache_(0, info->zone()), | 602 symbol_cache_(0, info->zone()), |
| 530 script_(info->script()), | 603 script_(info->script()), |
| 604 scanner_(isolate_->unicode_cache()), |
| 531 reusable_preparser_(NULL), | 605 reusable_preparser_(NULL), |
| 532 top_scope_(NULL), | |
| 533 original_scope_(NULL), | 606 original_scope_(NULL), |
| 534 current_function_state_(NULL), | |
| 535 target_stack_(NULL), | 607 target_stack_(NULL), |
| 536 extension_(info->extension()), | |
| 537 pre_parse_data_(NULL), | 608 pre_parse_data_(NULL), |
| 538 fni_(NULL), | 609 fni_(NULL), |
| 539 parenthesized_function_(false), | |
| 540 zone_(info->zone()), | |
| 541 info_(info) { | 610 info_(info) { |
| 542 ASSERT(!script_.is_null()); | 611 ASSERT(!script_.is_null()); |
| 543 isolate_->set_ast_node_id(0); | 612 isolate_->set_ast_node_id(0); |
| 544 set_allow_harmony_scoping(!info_->is_native() && FLAG_harmony_scoping); | 613 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 545 set_allow_modules(!info_->is_native() && FLAG_harmony_modules); | 614 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 546 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 615 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 547 set_allow_lazy(false); // Must be explicitly enabled. | 616 set_allow_lazy(false); // Must be explicitly enabled. |
| 548 set_allow_generators(FLAG_harmony_generators); | 617 set_allow_generators(FLAG_harmony_generators); |
| 549 set_allow_for_of(FLAG_harmony_iteration); | 618 set_allow_for_of(FLAG_harmony_iteration); |
| 550 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 619 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 551 } | 620 } |
| 552 | 621 |
| 553 | 622 |
| 554 FunctionLiteral* Parser::ParseProgram() { | 623 FunctionLiteral* Parser::ParseProgram() { |
| 555 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 624 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 556 // see comment for HistogramTimerScope class. | 625 // see comment for HistogramTimerScope class. |
| 557 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 626 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 558 Handle<String> source(String::cast(script_->source())); | 627 Handle<String> source(String::cast(script_->source())); |
| 559 isolate()->counters()->total_parse_size()->Increment(source->length()); | 628 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 560 ElapsedTimer timer; | 629 ElapsedTimer timer; |
| 561 if (FLAG_trace_parse) { | 630 if (FLAG_trace_parse) { |
| 562 timer.Start(); | 631 timer.Start(); |
| 563 } | 632 } |
| 564 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 633 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 565 | 634 |
| 566 // Initialize parser state. | 635 // Initialize parser state. |
| 567 source = FlattenGetString(source); | 636 source->TryFlatten(); |
| 568 FunctionLiteral* result; | 637 FunctionLiteral* result; |
| 569 delete reusable_preparser_; | 638 if (source->IsExternalTwoByteString()) { |
| 570 delete scanner_; | 639 // Notice that the stream is destroyed at the end of the branch block. |
| 571 if (source->IsTwoByteRepresentation()) { | 640 // The last line of the blocks can't be moved outside, even though they're |
| 572 scanner_ = new ExperimentalScanner<uint16_t>(source, isolate()); | 641 // identical calls. |
| 642 ExternalTwoByteStringUtf16CharacterStream stream( |
| 643 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 644 scanner_.Initialize(&stream); |
| 645 result = DoParseProgram(info(), source); |
| 573 } else { | 646 } else { |
| 574 scanner_ = new ExperimentalScanner<uint8_t>(source, isolate()); | 647 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 648 scanner_.Initialize(&stream); |
| 649 result = DoParseProgram(info(), source); |
| 575 } | 650 } |
| 576 SetScannerFlags(); | |
| 577 scanner_->Init(); | |
| 578 result = DoParseProgram(info(), source); | |
| 579 | 651 |
| 580 if (FLAG_trace_parse && result != NULL) { | 652 if (FLAG_trace_parse && result != NULL) { |
| 581 double ms = timer.Elapsed().InMillisecondsF(); | 653 double ms = timer.Elapsed().InMillisecondsF(); |
| 582 if (info()->is_eval()) { | 654 if (info()->is_eval()) { |
| 583 PrintF("[parsing eval"); | 655 PrintF("[parsing eval"); |
| 584 } else if (info()->script()->name()->IsString()) { | 656 } else if (info()->script()->name()->IsString()) { |
| 585 String* name = String::cast(info()->script()->name()); | 657 String* name = String::cast(info()->script()->name()); |
| 586 SmartArrayPointer<char> name_chars = name->ToCString(); | 658 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 587 PrintF("[parsing script: %s", name_chars.get()); | 659 PrintF("[parsing script: %s", name_chars.get()); |
| 588 } else { | 660 } else { |
| 589 PrintF("[parsing script"); | 661 PrintF("[parsing script"); |
| 590 } | 662 } |
| 591 PrintF(" - took %0.3f ms]\n", ms); | 663 PrintF(" - took %0.3f ms]\n", ms); |
| 592 } | 664 } |
| 593 return result; | 665 return result; |
| 594 } | 666 } |
| 595 | 667 |
| 596 | 668 |
| 597 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 669 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 598 Handle<String> source) { | 670 Handle<String> source) { |
| 599 ASSERT(top_scope_ == NULL); | 671 ASSERT(scope_ == NULL); |
| 600 ASSERT(target_stack_ == NULL); | 672 ASSERT(target_stack_ == NULL); |
| 601 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | 673 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
| 602 | 674 |
| 603 Handle<String> no_name = isolate()->factory()->empty_string(); | 675 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 604 | 676 |
| 605 FunctionLiteral* result = NULL; | 677 FunctionLiteral* result = NULL; |
| 606 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 678 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 607 info->SetGlobalScope(scope); | 679 info->SetGlobalScope(scope); |
| 608 if (!info->context().is_null()) { | 680 if (!info->context().is_null()) { |
| 609 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 681 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 610 } | 682 } |
| 611 original_scope_ = scope; | 683 original_scope_ = scope; |
| 612 if (info->is_eval()) { | 684 if (info->is_eval()) { |
| 613 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 685 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
| 614 scope = NewScope(scope, EVAL_SCOPE); | 686 scope = NewScope(scope, EVAL_SCOPE); |
| 615 } | 687 } |
| 616 } else if (info->is_global()) { | 688 } else if (info->is_global()) { |
| 617 scope = NewScope(scope, GLOBAL_SCOPE); | 689 scope = NewScope(scope, GLOBAL_SCOPE); |
| 618 } | 690 } |
| 619 scope->set_start_position(0); | 691 scope->set_start_position(0); |
| 620 scope->set_end_position(source->length()); | 692 scope->set_end_position(source->length()); |
| 621 | 693 |
| 622 // Compute the parsing mode. | 694 // Compute the parsing mode. |
| 623 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 695 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 624 if (allow_natives_syntax() || | 696 if (allow_natives_syntax() || |
| 625 extension_ != NULL || | 697 extension_ != NULL || |
| 626 scope->is_eval_scope()) { | 698 scope->is_eval_scope()) { |
| 627 mode = PARSE_EAGERLY; | 699 mode = PARSE_EAGERLY; |
| 628 } | 700 } |
| 629 ParsingModeScope parsing_mode(this, mode); | 701 ParsingModeScope parsing_mode(this, mode); |
| 630 | 702 |
| 631 // Enters 'scope'. | 703 // Enters 'scope'. |
| 632 FunctionState function_state(this, scope, isolate()); | 704 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 633 | 705 |
| 634 top_scope_->SetLanguageMode(info->language_mode()); | 706 scope_->SetLanguageMode(info->language_mode()); |
| 635 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 707 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 636 bool ok = true; | 708 bool ok = true; |
| 637 int beg_pos = scanner().location().beg_pos; | 709 int beg_pos = scanner()->location().beg_pos; |
| 638 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 710 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 639 if (ok && !top_scope_->is_classic_mode()) { | 711 if (ok && !scope_->is_classic_mode()) { |
| 640 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); | 712 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 641 } | 713 } |
| 642 | 714 |
| 643 if (ok && is_extended_mode()) { | 715 if (ok && is_extended_mode()) { |
| 644 CheckConflictingVarDeclarations(top_scope_, &ok); | 716 CheckConflictingVarDeclarations(scope_, &ok); |
| 645 } | 717 } |
| 646 | 718 |
| 647 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 719 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 648 if (body->length() != 1 || | 720 if (body->length() != 1 || |
| 649 !body->at(0)->IsExpressionStatement() || | 721 !body->at(0)->IsExpressionStatement() || |
| 650 !body->at(0)->AsExpressionStatement()-> | 722 !body->at(0)->AsExpressionStatement()-> |
| 651 expression()->IsFunctionLiteral()) { | 723 expression()->IsFunctionLiteral()) { |
| 652 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 724 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 653 ok = false; | 725 ok = false; |
| 654 } | 726 } |
| 655 } | 727 } |
| 656 | 728 |
| 657 if (ok) { | 729 if (ok) { |
| 658 result = factory()->NewFunctionLiteral( | 730 result = factory()->NewFunctionLiteral( |
| 659 no_name, | 731 no_name, |
| 660 top_scope_, | 732 scope_, |
| 661 body, | 733 body, |
| 662 function_state.materialized_literal_count(), | 734 function_state.materialized_literal_count(), |
| 663 function_state.expected_property_count(), | 735 function_state.expected_property_count(), |
| 664 function_state.handler_count(), | 736 function_state.handler_count(), |
| 665 0, | 737 0, |
| 666 FunctionLiteral::kNoDuplicateParameters, | 738 FunctionLiteral::kNoDuplicateParameters, |
| 667 FunctionLiteral::ANONYMOUS_EXPRESSION, | 739 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 668 FunctionLiteral::kGlobalOrEval, | 740 FunctionLiteral::kGlobalOrEval, |
| 669 FunctionLiteral::kNotParenthesized, | 741 FunctionLiteral::kNotParenthesized, |
| 670 FunctionLiteral::kNotGenerator, | 742 FunctionLiteral::kNotGenerator, |
| 671 0); | 743 0); |
| 672 result->set_ast_properties(factory()->visitor()->ast_properties()); | 744 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 745 result->set_slot_processor(factory()->visitor()->slot_processor()); |
| 673 result->set_dont_optimize_reason( | 746 result->set_dont_optimize_reason( |
| 674 factory()->visitor()->dont_optimize_reason()); | 747 factory()->visitor()->dont_optimize_reason()); |
| 675 } else if (stack_overflow()) { | 748 } else if (stack_overflow()) { |
| 676 isolate()->StackOverflow(); | 749 isolate()->StackOverflow(); |
| 677 } | 750 } |
| 678 } | 751 } |
| 679 | 752 |
| 680 // Make sure the target stack is empty. | 753 // Make sure the target stack is empty. |
| 681 ASSERT(target_stack_ == NULL); | 754 ASSERT(target_stack_ == NULL); |
| 682 | 755 |
| 683 return result; | 756 return result; |
| 684 } | 757 } |
| 685 | 758 |
| 686 | 759 |
| 687 FunctionLiteral* Parser::ParseLazy() { | 760 FunctionLiteral* Parser::ParseLazy() { |
| 688 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 761 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 689 Handle<String> source(String::cast(script_->source())); | 762 Handle<String> source(String::cast(script_->source())); |
| 690 isolate()->counters()->total_parse_size()->Increment(source->length()); | 763 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 691 ElapsedTimer timer; | 764 ElapsedTimer timer; |
| 692 if (FLAG_trace_parse) { | 765 if (FLAG_trace_parse) { |
| 693 timer.Start(); | 766 timer.Start(); |
| 694 } | 767 } |
| 768 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 769 |
| 695 // Initialize parser state. | 770 // Initialize parser state. |
| 696 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 771 source->TryFlatten(); |
| 697 FunctionLiteral* result = ParseLazy( | 772 FunctionLiteral* result; |
| 698 source, shared_info->start_position(), shared_info->end_position()); | 773 if (source->IsExternalTwoByteString()) { |
| 774 ExternalTwoByteStringUtf16CharacterStream stream( |
| 775 Handle<ExternalTwoByteString>::cast(source), |
| 776 shared_info->start_position(), |
| 777 shared_info->end_position()); |
| 778 result = ParseLazy(&stream); |
| 779 } else { |
| 780 GenericStringUtf16CharacterStream stream(source, |
| 781 shared_info->start_position(), |
| 782 shared_info->end_position()); |
| 783 result = ParseLazy(&stream); |
| 784 } |
| 785 |
| 699 if (FLAG_trace_parse && result != NULL) { | 786 if (FLAG_trace_parse && result != NULL) { |
| 700 double ms = timer.Elapsed().InMillisecondsF(); | 787 double ms = timer.Elapsed().InMillisecondsF(); |
| 701 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 788 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
| 702 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 789 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
| 703 } | 790 } |
| 704 return result; | 791 return result; |
| 705 } | 792 } |
| 706 | 793 |
| 707 | 794 |
| 708 FunctionLiteral* Parser::ParseLazy(Handle<String> source, int start, int end) { | 795 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 709 source = FlattenGetString(source); | |
| 710 delete reusable_preparser_; | |
| 711 delete scanner_; | |
| 712 if (source->IsTwoByteRepresentation()) { | |
| 713 scanner_ = new ExperimentalScanner<uint16_t>(source, isolate()); | |
| 714 } else { | |
| 715 scanner_ = new ExperimentalScanner<uint8_t>(source, isolate()); | |
| 716 } | |
| 717 SetScannerFlags(); | |
| 718 // We don't need to Init() if we immediately SeekForward. | |
| 719 scanner_->SeekForward(start); | |
| 720 scanner_->SetEnd(end); | |
| 721 | |
| 722 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 796 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 723 ASSERT(top_scope_ == NULL); | 797 scanner_.Initialize(source); |
| 798 ASSERT(scope_ == NULL); |
| 724 ASSERT(target_stack_ == NULL); | 799 ASSERT(target_stack_ == NULL); |
| 725 | 800 |
| 726 Handle<String> name(String::cast(shared_info->name())); | 801 Handle<String> name(String::cast(shared_info->name())); |
| 727 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 802 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 728 fni_->PushEnclosingName(name); | 803 fni_->PushEnclosingName(name); |
| 729 | 804 |
| 730 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 805 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 731 | 806 |
| 732 // Place holder for the result. | 807 // Place holder for the result. |
| 733 FunctionLiteral* result = NULL; | 808 FunctionLiteral* result = NULL; |
| 734 | 809 |
| 735 { | 810 { |
| 736 // Parse the function literal. | 811 // Parse the function literal. |
| 737 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 812 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 738 info()->SetGlobalScope(scope); | 813 info()->SetGlobalScope(scope); |
| 739 if (!info()->closure().is_null()) { | 814 if (!info()->closure().is_null()) { |
| 740 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 815 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 741 zone()); | 816 zone()); |
| 742 } | 817 } |
| 743 original_scope_ = scope; | 818 original_scope_ = scope; |
| 744 FunctionState function_state(this, scope, isolate()); | 819 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 745 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 820 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
| 746 ASSERT(scope->language_mode() != EXTENDED_MODE || | 821 ASSERT(scope->language_mode() != EXTENDED_MODE || |
| 747 info()->is_extended_mode()); | 822 info()->is_extended_mode()); |
| 748 ASSERT(info()->language_mode() == shared_info->language_mode()); | 823 ASSERT(info()->language_mode() == shared_info->language_mode()); |
| 749 scope->SetLanguageMode(shared_info->language_mode()); | 824 scope->SetLanguageMode(shared_info->language_mode()); |
| 750 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 825 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 751 ? (shared_info->is_anonymous() | 826 ? (shared_info->is_anonymous() |
| 752 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 827 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 753 : FunctionLiteral::NAMED_EXPRESSION) | 828 : FunctionLiteral::NAMED_EXPRESSION) |
| 754 : FunctionLiteral::DECLARATION; | 829 : FunctionLiteral::DECLARATION; |
| 755 bool ok = true; | 830 bool ok = true; |
| 756 result = ParseFunctionLiteral(name, | 831 result = ParseFunctionLiteral(name, |
| 832 Scanner::Location::invalid(), |
| 757 false, // Strict mode name already checked. | 833 false, // Strict mode name already checked. |
| 758 shared_info->is_generator(), | 834 shared_info->is_generator(), |
| 759 RelocInfo::kNoPosition, | 835 RelocInfo::kNoPosition, |
| 760 function_type, | 836 function_type, |
| 761 &ok); | 837 &ok); |
| 762 // Make sure the results agree. | 838 // Make sure the results agree. |
| 763 ASSERT(ok == (result != NULL)); | 839 ASSERT(ok == (result != NULL)); |
| 764 } | 840 } |
| 765 | 841 |
| 766 // Make sure the target stack is empty. | 842 // Make sure the target stack is empty. |
| 767 ASSERT(target_stack_ == NULL); | 843 ASSERT(target_stack_ == NULL); |
| 768 | 844 |
| 769 if (result == NULL) { | 845 if (result == NULL) { |
| 770 if (stack_overflow()) isolate()->StackOverflow(); | 846 if (stack_overflow()) isolate()->StackOverflow(); |
| 771 } else { | 847 } else { |
| 772 Handle<String> inferred_name(shared_info->inferred_name()); | 848 Handle<String> inferred_name(shared_info->inferred_name()); |
| 773 result->set_inferred_name(inferred_name); | 849 result->set_inferred_name(inferred_name); |
| 774 } | 850 } |
| 775 return result; | 851 return result; |
| 776 } | 852 } |
| 777 | 853 |
| 778 | 854 |
| 779 Handle<String> Parser::GetSymbol() { | |
| 780 int symbol_id = -1; | |
| 781 if (pre_parse_data() != NULL) { | |
| 782 symbol_id = pre_parse_data()->GetSymbolIdentifier(); | |
| 783 } | |
| 784 return LookupSymbol(symbol_id); | |
| 785 } | |
| 786 | |
| 787 | |
| 788 void Parser::ReportMessage(const char* message, Vector<const char*> args) { | |
| 789 ScannerBase::Location source_location = scanner().location(); | |
| 790 ReportMessageAt(source_location, message, args); | |
| 791 } | |
| 792 | |
| 793 | |
| 794 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { | |
| 795 ScannerBase::Location source_location = scanner().location(); | |
| 796 ReportMessageAt(source_location, message, args); | |
| 797 } | |
| 798 | |
| 799 | |
| 800 void Parser::ReportMessageAt(ScannerBase::Location source_location, | |
| 801 const char* message, | |
| 802 Vector<const char*> args) { | |
| 803 MessageLocation location(script_, | |
| 804 source_location.beg_pos, | |
| 805 source_location.end_pos); | |
| 806 Factory* factory = isolate()->factory(); | |
| 807 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 808 for (int i = 0; i < args.length(); i++) { | |
| 809 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | |
| 810 elements->set(i, *arg_string); | |
| 811 } | |
| 812 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 813 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 814 isolate()->Throw(*result, &location); | |
| 815 } | |
| 816 | |
| 817 | |
| 818 void Parser::ReportMessageAt(ScannerBase::Location source_location, | |
| 819 const char* message, | |
| 820 Vector<Handle<String> > args) { | |
| 821 MessageLocation location(script_, | |
| 822 source_location.beg_pos, | |
| 823 source_location.end_pos); | |
| 824 Factory* factory = isolate()->factory(); | |
| 825 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 826 for (int i = 0; i < args.length(); i++) { | |
| 827 elements->set(i, *args[i]); | |
| 828 } | |
| 829 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 830 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 831 isolate()->Throw(*result, &location); | |
| 832 } | |
| 833 | |
| 834 | |
| 835 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 855 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 836 int end_token, | 856 int end_token, |
| 837 bool is_eval, | 857 bool is_eval, |
| 838 bool is_global, | 858 bool is_global, |
| 839 bool* ok) { | 859 bool* ok) { |
| 840 // SourceElements :: | 860 // SourceElements :: |
| 841 // (ModuleElement)* <end_token> | 861 // (ModuleElement)* <end_token> |
| 842 | 862 |
| 843 // Allocate a target stack to use for this set of source | 863 // Allocate a target stack to use for this set of source |
| 844 // elements. This way, all scripts and functions get their own | 864 // elements. This way, all scripts and functions get their own |
| 845 // target stack thus avoiding illegal breaks and continues across | 865 // target stack thus avoiding illegal breaks and continues across |
| 846 // functions. | 866 // functions. |
| 847 TargetScope scope(&this->target_stack_); | 867 TargetScope scope(&this->target_stack_); |
| 848 | 868 |
| 849 ASSERT(processor != NULL); | 869 ASSERT(processor != NULL); |
| 850 bool directive_prologue = true; // Parsing directive prologue. | 870 bool directive_prologue = true; // Parsing directive prologue. |
| 851 | 871 |
| 852 while (peek() != end_token) { | 872 while (peek() != end_token) { |
| 853 if (directive_prologue && peek() != Token::STRING) { | 873 if (directive_prologue && peek() != Token::STRING) { |
| 854 directive_prologue = false; | 874 directive_prologue = false; |
| 855 } | 875 } |
| 856 | 876 |
| 857 ScannerBase::Location token_loc = scanner().peek_location(); | 877 Scanner::Location token_loc = scanner()->peek_location(); |
| 858 Statement* stat; | 878 Statement* stat; |
| 859 if (is_global && !is_eval) { | 879 if (is_global && !is_eval) { |
| 860 stat = ParseModuleElement(NULL, CHECK_OK); | 880 stat = ParseModuleElement(NULL, CHECK_OK); |
| 861 } else { | 881 } else { |
| 862 stat = ParseBlockElement(NULL, CHECK_OK); | 882 stat = ParseBlockElement(NULL, CHECK_OK); |
| 863 } | 883 } |
| 864 if (stat == NULL || stat->IsEmpty()) { | 884 if (stat == NULL || stat->IsEmpty()) { |
| 865 directive_prologue = false; // End of directive prologue. | 885 directive_prologue = false; // End of directive prologue. |
| 866 continue; | 886 continue; |
| 867 } | 887 } |
| 868 | 888 |
| 869 if (directive_prologue) { | 889 if (directive_prologue) { |
| 870 // A shot at a directive. | 890 // A shot at a directive. |
| 871 ExpressionStatement* e_stat; | 891 ExpressionStatement* e_stat; |
| 872 Literal* literal; | 892 Literal* literal; |
| 873 // Still processing directive prologue? | 893 // Still processing directive prologue? |
| 874 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 894 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 875 (literal = e_stat->expression()->AsLiteral()) != NULL && | 895 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 876 literal->value()->IsString()) { | 896 literal->value()->IsString()) { |
| 877 Handle<String> directive = Handle<String>::cast(literal->value()); | 897 Handle<String> directive = Handle<String>::cast(literal->value()); |
| 878 | 898 |
| 879 // Check "use strict" directive (ES5 14.1). | 899 // Check "use strict" directive (ES5 14.1). |
| 880 if (top_scope_->is_classic_mode() && | 900 if (scope_->is_classic_mode() && |
| 881 directive->Equals(isolate()->heap()->use_strict_string()) && | 901 directive->Equals(isolate()->heap()->use_strict_string()) && |
| 882 token_loc.end_pos - token_loc.beg_pos == | 902 token_loc.end_pos - token_loc.beg_pos == |
| 883 isolate()->heap()->use_strict_string()->length() + 2) { | 903 isolate()->heap()->use_strict_string()->length() + 2) { |
| 884 // TODO(mstarzinger): Global strict eval calls, need their own scope | 904 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 885 // as specified in ES5 10.4.2(3). The correct fix would be to always | 905 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 886 // add this scope in DoParseProgram(), but that requires adaptations | 906 // add this scope in DoParseProgram(), but that requires adaptations |
| 887 // all over the code base, so we go with a quick-fix for now. | 907 // all over the code base, so we go with a quick-fix for now. |
| 888 // In the same manner, we have to patch the parsing mode. | 908 // In the same manner, we have to patch the parsing mode. |
| 889 if (is_eval && !top_scope_->is_eval_scope()) { | 909 if (is_eval && !scope_->is_eval_scope()) { |
| 890 ASSERT(top_scope_->is_global_scope()); | 910 ASSERT(scope_->is_global_scope()); |
| 891 Scope* scope = NewScope(top_scope_, EVAL_SCOPE); | 911 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 892 scope->set_start_position(top_scope_->start_position()); | 912 scope->set_start_position(scope_->start_position()); |
| 893 scope->set_end_position(top_scope_->end_position()); | 913 scope->set_end_position(scope_->end_position()); |
| 894 top_scope_ = scope; | 914 scope_ = scope; |
| 895 mode_ = PARSE_EAGERLY; | 915 mode_ = PARSE_EAGERLY; |
| 896 } | 916 } |
| 897 // TODO(ES6): Fix entering extended mode, once it is specified. | 917 // TODO(ES6): Fix entering extended mode, once it is specified. |
| 898 top_scope_->SetLanguageMode(allow_harmony_scoping() | 918 scope_->SetLanguageMode(allow_harmony_scoping() |
| 899 ? EXTENDED_MODE : STRICT_MODE); | 919 ? EXTENDED_MODE : STRICT_MODE); |
| 900 // "use strict" is the only directive for now. | 920 // "use strict" is the only directive for now. |
| 901 directive_prologue = false; | 921 directive_prologue = false; |
| 902 } | 922 } |
| 903 } else { | 923 } else { |
| 904 // End of the directive prologue. | 924 // End of the directive prologue. |
| 905 directive_prologue = false; | 925 directive_prologue = false; |
| 906 } | 926 } |
| 907 } | 927 } |
| 908 | 928 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 937 return ParseVariableStatement(kModuleElement, NULL, ok); | 957 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 938 case Token::IMPORT: | 958 case Token::IMPORT: |
| 939 return ParseImportDeclaration(ok); | 959 return ParseImportDeclaration(ok); |
| 940 case Token::EXPORT: | 960 case Token::EXPORT: |
| 941 return ParseExportDeclaration(ok); | 961 return ParseExportDeclaration(ok); |
| 942 default: { | 962 default: { |
| 943 Statement* stmt = ParseStatement(labels, CHECK_OK); | 963 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 944 // Handle 'module' as a context-sensitive keyword. | 964 // Handle 'module' as a context-sensitive keyword. |
| 945 if (FLAG_harmony_modules && | 965 if (FLAG_harmony_modules && |
| 946 peek() == Token::IDENTIFIER && | 966 peek() == Token::IDENTIFIER && |
| 947 !scanner().HasAnyLineTerminatorBeforeNext() && | 967 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 948 stmt != NULL) { | 968 stmt != NULL) { |
| 949 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 969 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
| 950 if (estmt != NULL && | 970 if (estmt != NULL && |
| 951 estmt->expression()->AsVariableProxy() != NULL && | 971 estmt->expression()->AsVariableProxy() != NULL && |
| 952 estmt->expression()->AsVariableProxy()->name()->Equals( | 972 estmt->expression()->AsVariableProxy()->name()->Equals( |
| 953 isolate()->heap()->module_string()) && | 973 isolate()->heap()->module_string()) && |
| 954 !scanner().literal_contains_escapes()) { | 974 !scanner()->literal_contains_escapes()) { |
| 955 return ParseModuleDeclaration(NULL, ok); | 975 return ParseModuleDeclaration(NULL, ok); |
| 956 } | 976 } |
| 957 } | 977 } |
| 958 return stmt; | 978 return stmt; |
| 959 } | 979 } |
| 960 } | 980 } |
| 961 } | 981 } |
| 962 | 982 |
| 963 | 983 |
| 964 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 984 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 965 // ModuleDeclaration: | 985 // ModuleDeclaration: |
| 966 // 'module' Identifier Module | 986 // 'module' Identifier Module |
| 967 | 987 |
| 968 int pos = peek_position(); | 988 int pos = peek_position(); |
| 969 Handle<String> name = ParseIdentifier(CHECK_OK); | 989 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 970 | 990 |
| 971 #ifdef DEBUG | 991 #ifdef DEBUG |
| 972 if (FLAG_print_interface_details) | 992 if (FLAG_print_interface_details) |
| 973 PrintF("# Module %s...\n", name->ToAsciiArray()); | 993 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 974 #endif | 994 #endif |
| 975 | 995 |
| 976 Module* module = ParseModule(CHECK_OK); | 996 Module* module = ParseModule(CHECK_OK); |
| 977 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 997 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 978 Declaration* declaration = | 998 Declaration* declaration = |
| 979 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); | 999 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
| 980 Declare(declaration, true, CHECK_OK); | 1000 Declare(declaration, true, CHECK_OK); |
| 981 | 1001 |
| 982 #ifdef DEBUG | 1002 #ifdef DEBUG |
| 983 if (FLAG_print_interface_details) | 1003 if (FLAG_print_interface_details) |
| 984 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1004 PrintF("# Module %s.\n", name->ToAsciiArray()); |
| 985 | 1005 |
| 986 if (FLAG_print_interfaces) { | 1006 if (FLAG_print_interfaces) { |
| 987 PrintF("module %s : ", name->ToAsciiArray()); | 1007 PrintF("module %s : ", name->ToAsciiArray()); |
| 988 module->interface()->Print(); | 1008 module->interface()->Print(); |
| 989 } | 1009 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 Module* Parser::ParseModuleLiteral(bool* ok) { | 1047 Module* Parser::ParseModuleLiteral(bool* ok) { |
| 1028 // Module: | 1048 // Module: |
| 1029 // '{' ModuleElement '}' | 1049 // '{' ModuleElement '}' |
| 1030 | 1050 |
| 1031 int pos = peek_position(); | 1051 int pos = peek_position(); |
| 1032 // Construct block expecting 16 statements. | 1052 // Construct block expecting 16 statements. |
| 1033 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1053 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1034 #ifdef DEBUG | 1054 #ifdef DEBUG |
| 1035 if (FLAG_print_interface_details) PrintF("# Literal "); | 1055 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1036 #endif | 1056 #endif |
| 1037 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1057 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1038 | 1058 |
| 1039 Expect(Token::LBRACE, CHECK_OK); | 1059 Expect(Token::LBRACE, CHECK_OK); |
| 1040 scope->set_start_position(scanner().location().beg_pos); | 1060 scope->set_start_position(scanner()->location().beg_pos); |
| 1041 scope->SetLanguageMode(EXTENDED_MODE); | 1061 scope->SetLanguageMode(EXTENDED_MODE); |
| 1042 | 1062 |
| 1043 { | 1063 { |
| 1044 BlockState block_state(this, scope); | 1064 BlockState block_state(&scope_, scope); |
| 1045 TargetCollector collector(zone()); | 1065 TargetCollector collector(zone()); |
| 1046 Target target(&this->target_stack_, &collector); | 1066 Target target(&this->target_stack_, &collector); |
| 1047 Target target_body(&this->target_stack_, body); | 1067 Target target_body(&this->target_stack_, body); |
| 1048 | 1068 |
| 1049 while (peek() != Token::RBRACE) { | 1069 while (peek() != Token::RBRACE) { |
| 1050 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1070 Statement* stat = ParseModuleElement(NULL, CHECK_OK); |
| 1051 if (stat && !stat->IsEmpty()) { | 1071 if (stat && !stat->IsEmpty()) { |
| 1052 body->AddStatement(stat, zone()); | 1072 body->AddStatement(stat, zone()); |
| 1053 } | 1073 } |
| 1054 } | 1074 } |
| 1055 } | 1075 } |
| 1056 | 1076 |
| 1057 Expect(Token::RBRACE, CHECK_OK); | 1077 Expect(Token::RBRACE, CHECK_OK); |
| 1058 scope->set_end_position(scanner().location().end_pos); | 1078 scope->set_end_position(scanner()->location().end_pos); |
| 1059 body->set_scope(scope); | 1079 body->set_scope(scope); |
| 1060 | 1080 |
| 1061 // Check that all exports are bound. | 1081 // Check that all exports are bound. |
| 1062 Interface* interface = scope->interface(); | 1082 Interface* interface = scope->interface(); |
| 1063 for (Interface::Iterator it = interface->iterator(); | 1083 for (Interface::Iterator it = interface->iterator(); |
| 1064 !it.done(); it.Advance()) { | 1084 !it.done(); it.Advance()) { |
| 1065 if (scope->LocalLookup(it.name()) == NULL) { | 1085 if (scope->LocalLookup(it.name()) == NULL) { |
| 1066 Handle<String> name(it.name()); | 1086 Handle<String> name(it.name()); |
| 1067 ReportMessage("module_export_undefined", | 1087 ParserTraits::ReportMessage("module_export_undefined", |
| 1068 Vector<Handle<String> >(&name, 1)); | 1088 Vector<Handle<String> >(&name, 1)); |
| 1069 *ok = false; | 1089 *ok = false; |
| 1070 return NULL; | 1090 return NULL; |
| 1071 } | 1091 } |
| 1072 } | 1092 } |
| 1073 | 1093 |
| 1074 interface->MakeModule(ok); | 1094 interface->MakeModule(ok); |
| 1075 ASSERT(*ok); | 1095 ASSERT(*ok); |
| 1076 interface->Freeze(ok); | 1096 interface->Freeze(ok); |
| 1077 ASSERT(*ok); | 1097 ASSERT(*ok); |
| 1078 return factory()->NewModuleLiteral(body, interface, pos); | 1098 return factory()->NewModuleLiteral(body, interface, pos); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1097 if (!*ok) { | 1117 if (!*ok) { |
| 1098 #ifdef DEBUG | 1118 #ifdef DEBUG |
| 1099 if (FLAG_print_interfaces) { | 1119 if (FLAG_print_interfaces) { |
| 1100 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1120 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1101 PrintF("result: "); | 1121 PrintF("result: "); |
| 1102 result->interface()->Print(); | 1122 result->interface()->Print(); |
| 1103 PrintF("member: "); | 1123 PrintF("member: "); |
| 1104 member->interface()->Print(); | 1124 member->interface()->Print(); |
| 1105 } | 1125 } |
| 1106 #endif | 1126 #endif |
| 1107 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1127 ParserTraits::ReportMessage("invalid_module_path", |
| 1128 Vector<Handle<String> >(&name, 1)); |
| 1108 return NULL; | 1129 return NULL; |
| 1109 } | 1130 } |
| 1110 result = member; | 1131 result = member; |
| 1111 } | 1132 } |
| 1112 | 1133 |
| 1113 return result; | 1134 return result; |
| 1114 } | 1135 } |
| 1115 | 1136 |
| 1116 | 1137 |
| 1117 Module* Parser::ParseModuleVariable(bool* ok) { | 1138 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1118 // ModulePath: | 1139 // ModulePath: |
| 1119 // Identifier | 1140 // Identifier |
| 1120 | 1141 |
| 1121 int pos = peek_position(); | 1142 int pos = peek_position(); |
| 1122 Handle<String> name = ParseIdentifier(CHECK_OK); | 1143 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1123 #ifdef DEBUG | 1144 #ifdef DEBUG |
| 1124 if (FLAG_print_interface_details) | 1145 if (FLAG_print_interface_details) |
| 1125 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1146 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1126 #endif | 1147 #endif |
| 1127 VariableProxy* proxy = top_scope_->NewUnresolved( | 1148 VariableProxy* proxy = scope_->NewUnresolved( |
| 1128 factory(), name, Interface::NewModule(zone()), | 1149 factory(), name, Interface::NewModule(zone()), |
| 1129 scanner().location().beg_pos); | 1150 scanner()->location().beg_pos); |
| 1130 | 1151 |
| 1131 return factory()->NewModuleVariable(proxy, pos); | 1152 return factory()->NewModuleVariable(proxy, pos); |
| 1132 } | 1153 } |
| 1133 | 1154 |
| 1134 | 1155 |
| 1135 Module* Parser::ParseModuleUrl(bool* ok) { | 1156 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1136 // Module: | 1157 // Module: |
| 1137 // String | 1158 // String |
| 1138 | 1159 |
| 1139 int pos = peek_position(); | 1160 int pos = peek_position(); |
| 1140 Expect(Token::STRING, CHECK_OK); | 1161 Expect(Token::STRING, CHECK_OK); |
| 1141 Handle<String> symbol = GetSymbol(); | 1162 Handle<String> symbol = GetSymbol(); |
| 1142 | 1163 |
| 1143 // TODO(ES6): Request JS resource from environment... | 1164 // TODO(ES6): Request JS resource from environment... |
| 1144 | 1165 |
| 1145 #ifdef DEBUG | 1166 #ifdef DEBUG |
| 1146 if (FLAG_print_interface_details) PrintF("# Url "); | 1167 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1147 #endif | 1168 #endif |
| 1148 | 1169 |
| 1149 // Create an empty literal as long as the feature isn't finished. | 1170 // Create an empty literal as long as the feature isn't finished. |
| 1150 USE(symbol); | 1171 USE(symbol); |
| 1151 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1172 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1152 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1173 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1153 body->set_scope(scope); | 1174 body->set_scope(scope); |
| 1154 Interface* interface = scope->interface(); | 1175 Interface* interface = scope->interface(); |
| 1155 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1176 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1156 interface->Freeze(ok); | 1177 interface->Freeze(ok); |
| 1157 ASSERT(*ok); | 1178 ASSERT(*ok); |
| 1158 interface->Unify(scope->interface(), zone(), ok); | 1179 interface->Unify(scope->interface(), zone(), ok); |
| 1159 ASSERT(*ok); | 1180 ASSERT(*ok); |
| 1160 return result; | 1181 return result; |
| 1161 } | 1182 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 Interface* interface = Interface::NewUnknown(zone()); | 1228 Interface* interface = Interface::NewUnknown(zone()); |
| 1208 module->interface()->Add(names[i], interface, zone(), ok); | 1229 module->interface()->Add(names[i], interface, zone(), ok); |
| 1209 if (!*ok) { | 1230 if (!*ok) { |
| 1210 #ifdef DEBUG | 1231 #ifdef DEBUG |
| 1211 if (FLAG_print_interfaces) { | 1232 if (FLAG_print_interfaces) { |
| 1212 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1233 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1213 PrintF("module: "); | 1234 PrintF("module: "); |
| 1214 module->interface()->Print(); | 1235 module->interface()->Print(); |
| 1215 } | 1236 } |
| 1216 #endif | 1237 #endif |
| 1217 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1238 ParserTraits::ReportMessage("invalid_module_path", |
| 1239 Vector<Handle<String> >(&name, 1)); |
| 1218 return NULL; | 1240 return NULL; |
| 1219 } | 1241 } |
| 1220 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1242 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1221 Declaration* declaration = | 1243 Declaration* declaration = |
| 1222 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); | 1244 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
| 1223 Declare(declaration, true, CHECK_OK); | 1245 Declare(declaration, true, CHECK_OK); |
| 1224 } | 1246 } |
| 1225 | 1247 |
| 1226 return block; | 1248 return block; |
| 1227 } | 1249 } |
| 1228 | 1250 |
| 1229 | 1251 |
| 1230 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1252 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1231 // ExportDeclaration: | 1253 // ExportDeclaration: |
| 1232 // 'export' Identifier (',' Identifier)* ';' | 1254 // 'export' Identifier (',' Identifier)* ';' |
| 1233 // 'export' VariableDeclaration | 1255 // 'export' VariableDeclaration |
| 1234 // 'export' FunctionDeclaration | 1256 // 'export' FunctionDeclaration |
| 1235 // 'export' GeneratorDeclaration | 1257 // 'export' GeneratorDeclaration |
| 1236 // 'export' ModuleDeclaration | 1258 // 'export' ModuleDeclaration |
| 1237 // | 1259 // |
| 1238 // TODO(ES6): implement structuring ExportSpecifiers | 1260 // TODO(ES6): implement structuring ExportSpecifiers |
| 1239 | 1261 |
| 1240 Expect(Token::EXPORT, CHECK_OK); | 1262 Expect(Token::EXPORT, CHECK_OK); |
| 1241 | 1263 |
| 1242 Statement* result = NULL; | 1264 Statement* result = NULL; |
| 1243 ZoneStringList names(1, zone()); | 1265 ZoneStringList names(1, zone()); |
| 1244 switch (peek()) { | 1266 switch (peek()) { |
| 1245 case Token::IDENTIFIER: { | 1267 case Token::IDENTIFIER: { |
| 1246 int pos = position(); | 1268 int pos = position(); |
| 1247 Handle<String> name = ParseIdentifier(CHECK_OK); | 1269 Handle<String> name = |
| 1270 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1248 // Handle 'module' as a context-sensitive keyword. | 1271 // Handle 'module' as a context-sensitive keyword. |
| 1249 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1272 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1250 names.Add(name, zone()); | 1273 names.Add(name, zone()); |
| 1251 while (peek() == Token::COMMA) { | 1274 while (peek() == Token::COMMA) { |
| 1252 Consume(Token::COMMA); | 1275 Consume(Token::COMMA); |
| 1253 name = ParseIdentifier(CHECK_OK); | 1276 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1254 names.Add(name, zone()); | 1277 names.Add(name, zone()); |
| 1255 } | 1278 } |
| 1256 ExpectSemicolon(CHECK_OK); | 1279 ExpectSemicolon(CHECK_OK); |
| 1257 result = factory()->NewEmptyStatement(pos); | 1280 result = factory()->NewEmptyStatement(pos); |
| 1258 } else { | 1281 } else { |
| 1259 result = ParseModuleDeclaration(&names, CHECK_OK); | 1282 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1260 } | 1283 } |
| 1261 break; | 1284 break; |
| 1262 } | 1285 } |
| 1263 | 1286 |
| 1264 case Token::FUNCTION: | 1287 case Token::FUNCTION: |
| 1265 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1288 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1266 break; | 1289 break; |
| 1267 | 1290 |
| 1268 case Token::VAR: | 1291 case Token::VAR: |
| 1269 case Token::LET: | 1292 case Token::LET: |
| 1270 case Token::CONST: | 1293 case Token::CONST: |
| 1271 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1294 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); |
| 1272 break; | 1295 break; |
| 1273 | 1296 |
| 1274 default: | 1297 default: |
| 1275 *ok = false; | 1298 *ok = false; |
| 1276 ReportUnexpectedToken(scanner().current_token()); | 1299 ReportUnexpectedToken(scanner()->current_token()); |
| 1277 return NULL; | 1300 return NULL; |
| 1278 } | 1301 } |
| 1279 | 1302 |
| 1280 // Extract declared names into export declarations and interface. | 1303 // Extract declared names into export declarations and interface. |
| 1281 Interface* interface = top_scope_->interface(); | 1304 Interface* interface = scope_->interface(); |
| 1282 for (int i = 0; i < names.length(); ++i) { | 1305 for (int i = 0; i < names.length(); ++i) { |
| 1283 #ifdef DEBUG | 1306 #ifdef DEBUG |
| 1284 if (FLAG_print_interface_details) | 1307 if (FLAG_print_interface_details) |
| 1285 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1308 PrintF("# Export %s ", names[i]->ToAsciiArray()); |
| 1286 #endif | 1309 #endif |
| 1287 Interface* inner = Interface::NewUnknown(zone()); | 1310 Interface* inner = Interface::NewUnknown(zone()); |
| 1288 interface->Add(names[i], inner, zone(), CHECK_OK); | 1311 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1289 if (!*ok) | 1312 if (!*ok) |
| 1290 return NULL; | 1313 return NULL; |
| 1291 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1314 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1292 USE(proxy); | 1315 USE(proxy); |
| 1293 // TODO(rossberg): Rethink whether we actually need to store export | 1316 // TODO(rossberg): Rethink whether we actually need to store export |
| 1294 // declarations (for compilation?). | 1317 // declarations (for compilation?). |
| 1295 // ExportDeclaration* declaration = | 1318 // ExportDeclaration* declaration = |
| 1296 // factory()->NewExportDeclaration(proxy, top_scope_, position); | 1319 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1297 // top_scope_->AddDeclaration(declaration); | 1320 // scope_->AddDeclaration(declaration); |
| 1298 } | 1321 } |
| 1299 | 1322 |
| 1300 ASSERT(result != NULL); | 1323 ASSERT(result != NULL); |
| 1301 return result; | 1324 return result; |
| 1302 } | 1325 } |
| 1303 | 1326 |
| 1304 | 1327 |
| 1305 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1328 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| 1306 bool* ok) { | 1329 bool* ok) { |
| 1307 // (Ecma 262 5th Edition, clause 14): | 1330 // (Ecma 262 5th Edition, clause 14): |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 // (Ecma 262 5th Edition, clause 14): | 1436 // (Ecma 262 5th Edition, clause 14): |
| 1414 // SourceElement: | 1437 // SourceElement: |
| 1415 // Statement | 1438 // Statement |
| 1416 // FunctionDeclaration | 1439 // FunctionDeclaration |
| 1417 // Common language extension is to allow function declaration in place | 1440 // Common language extension is to allow function declaration in place |
| 1418 // of any statement. This language extension is disabled in strict mode. | 1441 // of any statement. This language extension is disabled in strict mode. |
| 1419 // | 1442 // |
| 1420 // In Harmony mode, this case also handles the extension: | 1443 // In Harmony mode, this case also handles the extension: |
| 1421 // Statement: | 1444 // Statement: |
| 1422 // GeneratorDeclaration | 1445 // GeneratorDeclaration |
| 1423 if (!top_scope_->is_classic_mode()) { | 1446 if (!scope_->is_classic_mode()) { |
| 1424 ReportMessageAt(scanner().peek_location(), "strict_function", | 1447 ReportMessageAt(scanner()->peek_location(), "strict_function"); |
| 1425 Vector<const char*>::empty()); | |
| 1426 *ok = false; | 1448 *ok = false; |
| 1427 return NULL; | 1449 return NULL; |
| 1428 } | 1450 } |
| 1429 return ParseFunctionDeclaration(NULL, ok); | 1451 return ParseFunctionDeclaration(NULL, ok); |
| 1430 } | 1452 } |
| 1431 | 1453 |
| 1432 case Token::DEBUGGER: | 1454 case Token::DEBUGGER: |
| 1433 return ParseDebuggerStatement(ok); | 1455 return ParseDebuggerStatement(ok); |
| 1434 | 1456 |
| 1435 default: | 1457 default: |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 if (!ok) { | 1616 if (!ok) { |
| 1595 #ifdef DEBUG | 1617 #ifdef DEBUG |
| 1596 if (FLAG_print_interfaces) { | 1618 if (FLAG_print_interfaces) { |
| 1597 PrintF("DECLARE TYPE ERROR\n"); | 1619 PrintF("DECLARE TYPE ERROR\n"); |
| 1598 PrintF("proxy: "); | 1620 PrintF("proxy: "); |
| 1599 proxy->interface()->Print(); | 1621 proxy->interface()->Print(); |
| 1600 PrintF("var: "); | 1622 PrintF("var: "); |
| 1601 var->interface()->Print(); | 1623 var->interface()->Print(); |
| 1602 } | 1624 } |
| 1603 #endif | 1625 #endif |
| 1604 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); | 1626 ParserTraits::ReportMessage("module_type_error", |
| 1627 Vector<Handle<String> >(&name, 1)); |
| 1605 } | 1628 } |
| 1606 } | 1629 } |
| 1607 } | 1630 } |
| 1608 } | 1631 } |
| 1609 | 1632 |
| 1610 | 1633 |
| 1611 // Language extension which is only enabled for source files loaded | 1634 // Language extension which is only enabled for source files loaded |
| 1612 // through the API's extension mechanism. A native function | 1635 // through the API's extension mechanism. A native function |
| 1613 // declaration is resolved by looking up the function through a | 1636 // declaration is resolved by looking up the function through a |
| 1614 // callback provided by the extension. | 1637 // callback provided by the extension. |
| 1615 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1638 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1616 int pos = peek_position(); | 1639 int pos = peek_position(); |
| 1617 Expect(Token::FUNCTION, CHECK_OK); | 1640 Expect(Token::FUNCTION, CHECK_OK); |
| 1618 Handle<String> name = ParseIdentifier(CHECK_OK); | 1641 // Allow "eval" or "arguments" for backward compatibility. |
| 1642 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1619 Expect(Token::LPAREN, CHECK_OK); | 1643 Expect(Token::LPAREN, CHECK_OK); |
| 1620 bool done = (peek() == Token::RPAREN); | 1644 bool done = (peek() == Token::RPAREN); |
| 1621 while (!done) { | 1645 while (!done) { |
| 1622 ParseIdentifier(CHECK_OK); | 1646 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1623 done = (peek() == Token::RPAREN); | 1647 done = (peek() == Token::RPAREN); |
| 1624 if (!done) { | 1648 if (!done) { |
| 1625 Expect(Token::COMMA, CHECK_OK); | 1649 Expect(Token::COMMA, CHECK_OK); |
| 1626 } | 1650 } |
| 1627 } | 1651 } |
| 1628 Expect(Token::RPAREN, CHECK_OK); | 1652 Expect(Token::RPAREN, CHECK_OK); |
| 1629 Expect(Token::SEMICOLON, CHECK_OK); | 1653 Expect(Token::SEMICOLON, CHECK_OK); |
| 1630 | 1654 |
| 1631 // Make sure that the function containing the native declaration | 1655 // Make sure that the function containing the native declaration |
| 1632 // isn't lazily compiled. The extension structures are only | 1656 // isn't lazily compiled. The extension structures are only |
| 1633 // accessible while parsing the first time not when reparsing | 1657 // accessible while parsing the first time not when reparsing |
| 1634 // because of lazy compilation. | 1658 // because of lazy compilation. |
| 1635 DeclarationScope(VAR)->ForceEagerCompilation(); | 1659 DeclarationScope(VAR)->ForceEagerCompilation(); |
| 1636 | 1660 |
| 1637 // TODO(1240846): It's weird that native function declarations are | 1661 // TODO(1240846): It's weird that native function declarations are |
| 1638 // introduced dynamically when we meet their declarations, whereas | 1662 // introduced dynamically when we meet their declarations, whereas |
| 1639 // other functions are set up when entering the surrounding scope. | 1663 // other functions are set up when entering the surrounding scope. |
| 1640 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1664 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
| 1641 Declaration* declaration = | 1665 Declaration* declaration = |
| 1642 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); | 1666 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); |
| 1643 Declare(declaration, true, CHECK_OK); | 1667 Declare(declaration, true, CHECK_OK); |
| 1644 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1668 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1645 name, extension_, RelocInfo::kNoPosition); | 1669 name, extension_, RelocInfo::kNoPosition); |
| 1646 return factory()->NewExpressionStatement( | 1670 return factory()->NewExpressionStatement( |
| 1647 factory()->NewAssignment( | 1671 factory()->NewAssignment( |
| 1648 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1672 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1649 pos); | 1673 pos); |
| 1650 } | 1674 } |
| 1651 | 1675 |
| 1652 | 1676 |
| 1653 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1677 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1654 // FunctionDeclaration :: | 1678 // FunctionDeclaration :: |
| 1655 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1679 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1656 // GeneratorDeclaration :: | 1680 // GeneratorDeclaration :: |
| 1657 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1681 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1658 // '{' FunctionBody '}' | 1682 // '{' FunctionBody '}' |
| 1659 Expect(Token::FUNCTION, CHECK_OK); | 1683 Expect(Token::FUNCTION, CHECK_OK); |
| 1660 int pos = position(); | 1684 int pos = position(); |
| 1661 bool is_generator = allow_generators() && Check(Token::MUL); | 1685 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1662 bool is_strict_reserved = false; | 1686 bool is_strict_reserved = false; |
| 1663 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1687 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1664 &is_strict_reserved, CHECK_OK); | 1688 &is_strict_reserved, CHECK_OK); |
| 1665 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1689 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1690 scanner()->location(), |
| 1666 is_strict_reserved, | 1691 is_strict_reserved, |
| 1667 is_generator, | 1692 is_generator, |
| 1668 pos, | 1693 pos, |
| 1669 FunctionLiteral::DECLARATION, | 1694 FunctionLiteral::DECLARATION, |
| 1670 CHECK_OK); | 1695 CHECK_OK); |
| 1671 // Even if we're not at the top-level of the global or a function | 1696 // Even if we're not at the top-level of the global or a function |
| 1672 // scope, we treat it as such and introduce the function with its | 1697 // scope, we treat it as such and introduce the function with its |
| 1673 // initial value upon entering the corresponding scope. | 1698 // initial value upon entering the corresponding scope. |
| 1674 // In extended mode, a function behaves as a lexical binding, except in the | 1699 // In extended mode, a function behaves as a lexical binding, except in the |
| 1675 // global scope. | 1700 // global scope. |
| 1676 VariableMode mode = | 1701 VariableMode mode = |
| 1677 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1702 is_extended_mode() && !scope_->is_global_scope() ? LET : VAR; |
| 1678 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1703 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1679 Declaration* declaration = | 1704 Declaration* declaration = |
| 1680 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); | 1705 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1681 Declare(declaration, true, CHECK_OK); | 1706 Declare(declaration, true, CHECK_OK); |
| 1682 if (names) names->Add(name, zone()); | 1707 if (names) names->Add(name, zone()); |
| 1683 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1708 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1684 } | 1709 } |
| 1685 | 1710 |
| 1686 | 1711 |
| 1687 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1712 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1688 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1713 if (scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
| 1689 | 1714 |
| 1690 // Block :: | 1715 // Block :: |
| 1691 // '{' Statement* '}' | 1716 // '{' Statement* '}' |
| 1692 | 1717 |
| 1693 // Note that a Block does not introduce a new execution scope! | 1718 // Note that a Block does not introduce a new execution scope! |
| 1694 // (ECMA-262, 3rd, 12.2) | 1719 // (ECMA-262, 3rd, 12.2) |
| 1695 // | 1720 // |
| 1696 // Construct block expecting 16 statements. | 1721 // Construct block expecting 16 statements. |
| 1697 Block* result = | 1722 Block* result = |
| 1698 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1723 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1711 | 1736 |
| 1712 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1737 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1713 // The harmony mode uses block elements instead of statements. | 1738 // The harmony mode uses block elements instead of statements. |
| 1714 // | 1739 // |
| 1715 // Block :: | 1740 // Block :: |
| 1716 // '{' BlockElement* '}' | 1741 // '{' BlockElement* '}' |
| 1717 | 1742 |
| 1718 // Construct block expecting 16 statements. | 1743 // Construct block expecting 16 statements. |
| 1719 Block* body = | 1744 Block* body = |
| 1720 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1745 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1721 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1746 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 1722 | 1747 |
| 1723 // Parse the statements and collect escaping labels. | 1748 // Parse the statements and collect escaping labels. |
| 1724 Expect(Token::LBRACE, CHECK_OK); | 1749 Expect(Token::LBRACE, CHECK_OK); |
| 1725 block_scope->set_start_position(scanner().location().beg_pos); | 1750 block_scope->set_start_position(scanner()->location().beg_pos); |
| 1726 { BlockState block_state(this, block_scope); | 1751 { BlockState block_state(&scope_, block_scope); |
| 1727 TargetCollector collector(zone()); | 1752 TargetCollector collector(zone()); |
| 1728 Target target(&this->target_stack_, &collector); | 1753 Target target(&this->target_stack_, &collector); |
| 1729 Target target_body(&this->target_stack_, body); | 1754 Target target_body(&this->target_stack_, body); |
| 1730 | 1755 |
| 1731 while (peek() != Token::RBRACE) { | 1756 while (peek() != Token::RBRACE) { |
| 1732 Statement* stat = ParseBlockElement(NULL, CHECK_OK); | 1757 Statement* stat = ParseBlockElement(NULL, CHECK_OK); |
| 1733 if (stat && !stat->IsEmpty()) { | 1758 if (stat && !stat->IsEmpty()) { |
| 1734 body->AddStatement(stat, zone()); | 1759 body->AddStatement(stat, zone()); |
| 1735 } | 1760 } |
| 1736 } | 1761 } |
| 1737 } | 1762 } |
| 1738 Expect(Token::RBRACE, CHECK_OK); | 1763 Expect(Token::RBRACE, CHECK_OK); |
| 1739 block_scope->set_end_position(scanner().location().end_pos); | 1764 block_scope->set_end_position(scanner()->location().end_pos); |
| 1740 block_scope = block_scope->FinalizeBlockScope(); | 1765 block_scope = block_scope->FinalizeBlockScope(); |
| 1741 body->set_scope(block_scope); | 1766 body->set_scope(block_scope); |
| 1742 return body; | 1767 return body; |
| 1743 } | 1768 } |
| 1744 | 1769 |
| 1745 | 1770 |
| 1746 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1771 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1747 ZoneStringList* names, | 1772 ZoneStringList* names, |
| 1748 bool* ok) { | 1773 bool* ok) { |
| 1749 // VariableStatement :: | 1774 // VariableStatement :: |
| 1750 // VariableDeclarations ';' | 1775 // VariableDeclarations ';' |
| 1751 | 1776 |
| 1752 Handle<String> ignore; | 1777 Handle<String> ignore; |
| 1753 Block* result = | 1778 Block* result = |
| 1754 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1779 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1755 ExpectSemicolon(CHECK_OK); | 1780 ExpectSemicolon(CHECK_OK); |
| 1756 return result; | 1781 return result; |
| 1757 } | 1782 } |
| 1758 | 1783 |
| 1759 | 1784 |
| 1760 bool Parser::IsEvalOrArguments(Handle<String> string) { | |
| 1761 return string.is_identical_to(isolate()->factory()->eval_string()) || | |
| 1762 string.is_identical_to(isolate()->factory()->arguments_string()); | |
| 1763 } | |
| 1764 | |
| 1765 | |
| 1766 // If the variable declaration declares exactly one non-const | 1785 // If the variable declaration declares exactly one non-const |
| 1767 // variable, then *out is set to that variable. In all other cases, | 1786 // variable, then *out is set to that variable. In all other cases, |
| 1768 // *out is untouched; in particular, it is the caller's responsibility | 1787 // *out is untouched; in particular, it is the caller's responsibility |
| 1769 // to initialize it properly. This mechanism is used for the parsing | 1788 // to initialize it properly. This mechanism is used for the parsing |
| 1770 // of 'for-in' loops. | 1789 // of 'for-in' loops. |
| 1771 Block* Parser::ParseVariableDeclarations( | 1790 Block* Parser::ParseVariableDeclarations( |
| 1772 VariableDeclarationContext var_context, | 1791 VariableDeclarationContext var_context, |
| 1773 VariableDeclarationProperties* decl_props, | 1792 VariableDeclarationProperties* decl_props, |
| 1774 ZoneStringList* names, | 1793 ZoneStringList* names, |
| 1775 Handle<String>* out, | 1794 Handle<String>* out, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1804 // | 1823 // |
| 1805 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 1824 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 1806 // | 1825 // |
| 1807 // * It is a Syntax Error if the code that matches this production is not | 1826 // * It is a Syntax Error if the code that matches this production is not |
| 1808 // contained in extended code. | 1827 // contained in extended code. |
| 1809 // | 1828 // |
| 1810 // However disallowing const in classic mode will break compatibility with | 1829 // However disallowing const in classic mode will break compatibility with |
| 1811 // existing pages. Therefore we keep allowing const with the old | 1830 // existing pages. Therefore we keep allowing const with the old |
| 1812 // non-harmony semantics in classic mode. | 1831 // non-harmony semantics in classic mode. |
| 1813 Consume(Token::CONST); | 1832 Consume(Token::CONST); |
| 1814 switch (top_scope_->language_mode()) { | 1833 switch (scope_->language_mode()) { |
| 1815 case CLASSIC_MODE: | 1834 case CLASSIC_MODE: |
| 1816 mode = CONST; | 1835 mode = CONST; |
| 1817 init_op = Token::INIT_CONST; | 1836 init_op = Token::INIT_CONST; |
| 1818 break; | 1837 break; |
| 1819 case STRICT_MODE: | 1838 case STRICT_MODE: |
| 1820 ReportMessage("strict_const", Vector<const char*>::empty()); | 1839 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1821 *ok = false; | 1840 *ok = false; |
| 1822 return NULL; | 1841 return NULL; |
| 1823 case EXTENDED_MODE: | 1842 case EXTENDED_MODE: |
| 1824 if (var_context == kStatement) { | 1843 if (var_context == kStatement) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 // | 1894 // |
| 1876 // Create new block with one expected declaration. | 1895 // Create new block with one expected declaration. |
| 1877 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 1896 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 1878 int nvars = 0; // the number of variables declared | 1897 int nvars = 0; // the number of variables declared |
| 1879 Handle<String> name; | 1898 Handle<String> name; |
| 1880 do { | 1899 do { |
| 1881 if (fni_ != NULL) fni_->Enter(); | 1900 if (fni_ != NULL) fni_->Enter(); |
| 1882 | 1901 |
| 1883 // Parse variable name. | 1902 // Parse variable name. |
| 1884 if (nvars > 0) Consume(Token::COMMA); | 1903 if (nvars > 0) Consume(Token::COMMA); |
| 1885 name = ParseIdentifier(CHECK_OK); | 1904 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1886 if (fni_ != NULL) fni_->PushVariableName(name); | 1905 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1887 | 1906 |
| 1888 // Strict mode variables may not be named eval or arguments | |
| 1889 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 1890 ReportMessage("strict_var_name", Vector<const char*>::empty()); | |
| 1891 *ok = false; | |
| 1892 return NULL; | |
| 1893 } | |
| 1894 | |
| 1895 // Declare variable. | 1907 // Declare variable. |
| 1896 // Note that we *always* must treat the initial value via a separate init | 1908 // Note that we *always* must treat the initial value via a separate init |
| 1897 // assignment for variables and constants because the value must be assigned | 1909 // assignment for variables and constants because the value must be assigned |
| 1898 // when the variable is encountered in the source. But the variable/constant | 1910 // when the variable is encountered in the source. But the variable/constant |
| 1899 // is declared (and set to 'undefined') upon entering the function within | 1911 // is declared (and set to 'undefined') upon entering the function within |
| 1900 // which the variable or constant is declared. Only function variables have | 1912 // which the variable or constant is declared. Only function variables have |
| 1901 // an initial value in the declaration (because they are initialized upon | 1913 // an initial value in the declaration (because they are initialized upon |
| 1902 // entering the function). | 1914 // entering the function). |
| 1903 // | 1915 // |
| 1904 // If we have a const declaration, in an inner scope, the proxy is always | 1916 // If we have a const declaration, in an inner scope, the proxy is always |
| 1905 // bound to the declared variable (independent of possibly surrounding with | 1917 // bound to the declared variable (independent of possibly surrounding with |
| 1906 // statements). | 1918 // statements). |
| 1907 // For let/const declarations in harmony mode, we can also immediately | 1919 // For let/const declarations in harmony mode, we can also immediately |
| 1908 // pre-resolve the proxy because it resides in the same scope as the | 1920 // pre-resolve the proxy because it resides in the same scope as the |
| 1909 // declaration. | 1921 // declaration. |
| 1910 Interface* interface = | 1922 Interface* interface = |
| 1911 is_const ? Interface::NewConst() : Interface::NewValue(); | 1923 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 1912 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1924 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 1913 Declaration* declaration = | 1925 Declaration* declaration = |
| 1914 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); | 1926 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 1915 Declare(declaration, mode != VAR, CHECK_OK); | 1927 Declare(declaration, mode != VAR, CHECK_OK); |
| 1916 nvars++; | 1928 nvars++; |
| 1917 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1929 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1918 ReportMessageAt(scanner().location(), "too_many_variables", | 1930 ReportMessageAt(scanner()->location(), "too_many_variables"); |
| 1919 Vector<const char*>::empty()); | |
| 1920 *ok = false; | 1931 *ok = false; |
| 1921 return NULL; | 1932 return NULL; |
| 1922 } | 1933 } |
| 1923 if (names) names->Add(name, zone()); | 1934 if (names) names->Add(name, zone()); |
| 1924 | 1935 |
| 1925 // Parse initialization expression if present and/or needed. A | 1936 // Parse initialization expression if present and/or needed. A |
| 1926 // declaration of the form: | 1937 // declaration of the form: |
| 1927 // | 1938 // |
| 1928 // var v = x; | 1939 // var v = x; |
| 1929 // | 1940 // |
| 1930 // is syntactic sugar for: | 1941 // is syntactic sugar for: |
| 1931 // | 1942 // |
| 1932 // var v; v = x; | 1943 // var v; v = x; |
| 1933 // | 1944 // |
| 1934 // In particular, we need to re-lookup 'v' (in top_scope_, not | 1945 // In particular, we need to re-lookup 'v' (in scope_, not |
| 1935 // declaration_scope) as it may be a different 'v' than the 'v' in the | 1946 // declaration_scope) as it may be a different 'v' than the 'v' in the |
| 1936 // declaration (e.g., if we are inside a 'with' statement or 'catch' | 1947 // declaration (e.g., if we are inside a 'with' statement or 'catch' |
| 1937 // block). | 1948 // block). |
| 1938 // | 1949 // |
| 1939 // However, note that const declarations are different! A const | 1950 // However, note that const declarations are different! A const |
| 1940 // declaration of the form: | 1951 // declaration of the form: |
| 1941 // | 1952 // |
| 1942 // const c = x; | 1953 // const c = x; |
| 1943 // | 1954 // |
| 1944 // is *not* syntactic sugar for: | 1955 // is *not* syntactic sugar for: |
| 1945 // | 1956 // |
| 1946 // const c; c = x; | 1957 // const c; c = x; |
| 1947 // | 1958 // |
| 1948 // The "variable" c initialized to x is the same as the declared | 1959 // The "variable" c initialized to x is the same as the declared |
| 1949 // one - there is no re-lookup (see the last parameter of the | 1960 // one - there is no re-lookup (see the last parameter of the |
| 1950 // Declare() call above). | 1961 // Declare() call above). |
| 1951 | 1962 |
| 1952 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1963 Scope* initialization_scope = is_const ? declaration_scope : scope_; |
| 1953 Expression* value = NULL; | 1964 Expression* value = NULL; |
| 1954 int pos = -1; | 1965 int pos = -1; |
| 1955 // Harmony consts have non-optional initializers. | 1966 // Harmony consts have non-optional initializers. |
| 1956 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 1967 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
| 1957 Expect(Token::ASSIGN, CHECK_OK); | 1968 Expect(Token::ASSIGN, CHECK_OK); |
| 1958 pos = position(); | 1969 pos = position(); |
| 1959 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1970 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1960 // Don't infer if it is "a = function(){...}();"-like expression. | 1971 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1961 if (fni_ != NULL && | 1972 if (fni_ != NULL && |
| 1962 value->AsCall() == NULL && | 1973 value->AsCall() == NULL && |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2133 *ok = false; | 2144 *ok = false; |
| 2134 return NULL; | 2145 return NULL; |
| 2135 } | 2146 } |
| 2136 if (labels == NULL) { | 2147 if (labels == NULL) { |
| 2137 labels = new(zone()) ZoneStringList(4, zone()); | 2148 labels = new(zone()) ZoneStringList(4, zone()); |
| 2138 } | 2149 } |
| 2139 labels->Add(label, zone()); | 2150 labels->Add(label, zone()); |
| 2140 // Remove the "ghost" variable that turned out to be a label | 2151 // Remove the "ghost" variable that turned out to be a label |
| 2141 // from the top scope. This way, we don't try to resolve it | 2152 // from the top scope. This way, we don't try to resolve it |
| 2142 // during the scope processing. | 2153 // during the scope processing. |
| 2143 top_scope_->RemoveUnresolved(var); | 2154 scope_->RemoveUnresolved(var); |
| 2144 Expect(Token::COLON, CHECK_OK); | 2155 Expect(Token::COLON, CHECK_OK); |
| 2145 return ParseStatement(labels, ok); | 2156 return ParseStatement(labels, ok); |
| 2146 } | 2157 } |
| 2147 | 2158 |
| 2148 // If we have an extension, we allow a native function declaration. | 2159 // If we have an extension, we allow a native function declaration. |
| 2149 // A native function declaration starts with "native function" with | 2160 // A native function declaration starts with "native function" with |
| 2150 // no line-terminator between the two words. | 2161 // no line-terminator between the two words. |
| 2151 if (extension_ != NULL && | 2162 if (extension_ != NULL && |
| 2152 peek() == Token::FUNCTION && | 2163 peek() == Token::FUNCTION && |
| 2153 !scanner().HasAnyLineTerminatorBeforeNext() && | 2164 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2154 expr != NULL && | 2165 expr != NULL && |
| 2155 expr->AsVariableProxy() != NULL && | 2166 expr->AsVariableProxy() != NULL && |
| 2156 expr->AsVariableProxy()->name()->Equals( | 2167 expr->AsVariableProxy()->name()->Equals( |
| 2157 isolate()->heap()->native_string()) && | 2168 isolate()->heap()->native_string()) && |
| 2158 !scanner().literal_contains_escapes()) { | 2169 !scanner()->literal_contains_escapes()) { |
| 2159 return ParseNativeDeclaration(ok); | 2170 return ParseNativeDeclaration(ok); |
| 2160 } | 2171 } |
| 2161 | 2172 |
| 2162 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2173 // Parsed expression statement, or the context-sensitive 'module' keyword. |
| 2163 // Only expect semicolon in the former case. | 2174 // Only expect semicolon in the former case. |
| 2164 if (!FLAG_harmony_modules || | 2175 if (!FLAG_harmony_modules || |
| 2165 peek() != Token::IDENTIFIER || | 2176 peek() != Token::IDENTIFIER || |
| 2166 scanner().HasAnyLineTerminatorBeforeNext() || | 2177 scanner()->HasAnyLineTerminatorBeforeNext() || |
| 2167 expr->AsVariableProxy() == NULL || | 2178 expr->AsVariableProxy() == NULL || |
| 2168 !expr->AsVariableProxy()->name()->Equals( | 2179 !expr->AsVariableProxy()->name()->Equals( |
| 2169 isolate()->heap()->module_string()) || | 2180 isolate()->heap()->module_string()) || |
| 2170 scanner().literal_contains_escapes()) { | 2181 scanner()->literal_contains_escapes()) { |
| 2171 ExpectSemicolon(CHECK_OK); | 2182 ExpectSemicolon(CHECK_OK); |
| 2172 } | 2183 } |
| 2173 return factory()->NewExpressionStatement(expr, pos); | 2184 return factory()->NewExpressionStatement(expr, pos); |
| 2174 } | 2185 } |
| 2175 | 2186 |
| 2176 | 2187 |
| 2177 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2188 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2178 // IfStatement :: | 2189 // IfStatement :: |
| 2179 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2190 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2180 | 2191 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2197 | 2208 |
| 2198 | 2209 |
| 2199 Statement* Parser::ParseContinueStatement(bool* ok) { | 2210 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2200 // ContinueStatement :: | 2211 // ContinueStatement :: |
| 2201 // 'continue' Identifier? ';' | 2212 // 'continue' Identifier? ';' |
| 2202 | 2213 |
| 2203 int pos = peek_position(); | 2214 int pos = peek_position(); |
| 2204 Expect(Token::CONTINUE, CHECK_OK); | 2215 Expect(Token::CONTINUE, CHECK_OK); |
| 2205 Handle<String> label = Handle<String>::null(); | 2216 Handle<String> label = Handle<String>::null(); |
| 2206 Token::Value tok = peek(); | 2217 Token::Value tok = peek(); |
| 2207 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2218 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2208 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2219 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2209 label = ParseIdentifier(CHECK_OK); | 2220 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2221 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2210 } | 2222 } |
| 2211 IterationStatement* target = NULL; | 2223 IterationStatement* target = NULL; |
| 2212 target = LookupContinueTarget(label, CHECK_OK); | 2224 target = LookupContinueTarget(label, CHECK_OK); |
| 2213 if (target == NULL) { | 2225 if (target == NULL) { |
| 2214 // Illegal continue statement. | 2226 // Illegal continue statement. |
| 2215 const char* message = "illegal_continue"; | 2227 const char* message = "illegal_continue"; |
| 2216 Vector<Handle<String> > args; | 2228 Vector<Handle<String> > args; |
| 2217 if (!label.is_null()) { | 2229 if (!label.is_null()) { |
| 2218 message = "unknown_label"; | 2230 message = "unknown_label"; |
| 2219 args = Vector<Handle<String> >(&label, 1); | 2231 args = Vector<Handle<String> >(&label, 1); |
| 2220 } | 2232 } |
| 2221 ReportMessageAt(scanner().location(), message, args); | 2233 ParserTraits::ReportMessageAt(scanner()->location(), message, args); |
| 2222 *ok = false; | 2234 *ok = false; |
| 2223 return NULL; | 2235 return NULL; |
| 2224 } | 2236 } |
| 2225 ExpectSemicolon(CHECK_OK); | 2237 ExpectSemicolon(CHECK_OK); |
| 2226 return factory()->NewContinueStatement(target, pos); | 2238 return factory()->NewContinueStatement(target, pos); |
| 2227 } | 2239 } |
| 2228 | 2240 |
| 2229 | 2241 |
| 2230 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2242 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2231 // BreakStatement :: | 2243 // BreakStatement :: |
| 2232 // 'break' Identifier? ';' | 2244 // 'break' Identifier? ';' |
| 2233 | 2245 |
| 2234 int pos = peek_position(); | 2246 int pos = peek_position(); |
| 2235 Expect(Token::BREAK, CHECK_OK); | 2247 Expect(Token::BREAK, CHECK_OK); |
| 2236 Handle<String> label; | 2248 Handle<String> label; |
| 2237 Token::Value tok = peek(); | 2249 Token::Value tok = peek(); |
| 2238 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2250 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2239 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2251 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2240 label = ParseIdentifier(CHECK_OK); | 2252 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2253 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2241 } | 2254 } |
| 2242 // Parse labeled break statements that target themselves into | 2255 // Parse labeled break statements that target themselves into |
| 2243 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2256 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2244 if (!label.is_null() && ContainsLabel(labels, label)) { | 2257 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2245 ExpectSemicolon(CHECK_OK); | 2258 ExpectSemicolon(CHECK_OK); |
| 2246 return factory()->NewEmptyStatement(pos); | 2259 return factory()->NewEmptyStatement(pos); |
| 2247 } | 2260 } |
| 2248 BreakableStatement* target = NULL; | 2261 BreakableStatement* target = NULL; |
| 2249 target = LookupBreakTarget(label, CHECK_OK); | 2262 target = LookupBreakTarget(label, CHECK_OK); |
| 2250 if (target == NULL) { | 2263 if (target == NULL) { |
| 2251 // Illegal break statement. | 2264 // Illegal break statement. |
| 2252 const char* message = "illegal_break"; | 2265 const char* message = "illegal_break"; |
| 2253 Vector<Handle<String> > args; | 2266 Vector<Handle<String> > args; |
| 2254 if (!label.is_null()) { | 2267 if (!label.is_null()) { |
| 2255 message = "unknown_label"; | 2268 message = "unknown_label"; |
| 2256 args = Vector<Handle<String> >(&label, 1); | 2269 args = Vector<Handle<String> >(&label, 1); |
| 2257 } | 2270 } |
| 2258 ReportMessageAt(scanner().location(), message, args); | 2271 ParserTraits::ReportMessageAt(scanner()->location(), message, args); |
| 2259 *ok = false; | 2272 *ok = false; |
| 2260 return NULL; | 2273 return NULL; |
| 2261 } | 2274 } |
| 2262 ExpectSemicolon(CHECK_OK); | 2275 ExpectSemicolon(CHECK_OK); |
| 2263 return factory()->NewBreakStatement(target, pos); | 2276 return factory()->NewBreakStatement(target, pos); |
| 2264 } | 2277 } |
| 2265 | 2278 |
| 2266 | 2279 |
| 2267 Statement* Parser::ParseReturnStatement(bool* ok) { | 2280 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2268 // ReturnStatement :: | 2281 // ReturnStatement :: |
| 2269 // 'return' Expression? ';' | 2282 // 'return' Expression? ';' |
| 2270 | 2283 |
| 2271 // Consume the return token. It is necessary to do that before | 2284 // Consume the return token. It is necessary to do that before |
| 2272 // reporting any errors on it, because of the way errors are | 2285 // reporting any errors on it, because of the way errors are |
| 2273 // reported (underlining). | 2286 // reported (underlining). |
| 2274 Expect(Token::RETURN, CHECK_OK); | 2287 Expect(Token::RETURN, CHECK_OK); |
| 2275 int pos = position(); | 2288 int pos = position(); |
| 2276 | 2289 |
| 2277 Token::Value tok = peek(); | 2290 Token::Value tok = peek(); |
| 2278 Statement* result; | 2291 Statement* result; |
| 2279 Expression* return_value; | 2292 Expression* return_value; |
| 2280 if (scanner().HasAnyLineTerminatorBeforeNext() || | 2293 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
| 2281 tok == Token::SEMICOLON || | 2294 tok == Token::SEMICOLON || |
| 2282 tok == Token::RBRACE || | 2295 tok == Token::RBRACE || |
| 2283 tok == Token::EOS) { | 2296 tok == Token::EOS) { |
| 2284 return_value = GetLiteralUndefined(position()); | 2297 return_value = GetLiteralUndefined(position()); |
| 2285 } else { | 2298 } else { |
| 2286 return_value = ParseExpression(true, CHECK_OK); | 2299 return_value = ParseExpression(true, CHECK_OK); |
| 2287 } | 2300 } |
| 2288 ExpectSemicolon(CHECK_OK); | 2301 ExpectSemicolon(CHECK_OK); |
| 2289 if (is_generator()) { | 2302 if (is_generator()) { |
| 2290 Expression* generator = factory()->NewVariableProxy( | 2303 Expression* generator = factory()->NewVariableProxy( |
| 2291 current_function_state_->generator_object_variable()); | 2304 function_state_->generator_object_variable()); |
| 2292 Expression* yield = factory()->NewYield( | 2305 Expression* yield = factory()->NewYield( |
| 2293 generator, return_value, Yield::FINAL, pos); | 2306 generator, return_value, Yield::FINAL, pos); |
| 2294 result = factory()->NewExpressionStatement(yield, pos); | 2307 result = factory()->NewExpressionStatement(yield, pos); |
| 2295 } else { | 2308 } else { |
| 2296 result = factory()->NewReturnStatement(return_value, pos); | 2309 result = factory()->NewReturnStatement(return_value, pos); |
| 2297 } | 2310 } |
| 2298 | 2311 |
| 2299 // An ECMAScript program is considered syntactically incorrect if it | 2312 // An ECMAScript program is considered syntactically incorrect if it |
| 2300 // contains a return statement that is not within the body of a | 2313 // contains a return statement that is not within the body of a |
| 2301 // function. See ECMA-262, section 12.9, page 67. | 2314 // function. See ECMA-262, section 12.9, page 67. |
| 2302 // | 2315 // |
| 2303 // To be consistent with KJS we report the syntax error at runtime. | 2316 // To be consistent with KJS we report the syntax error at runtime. |
| 2304 Scope* declaration_scope = top_scope_->DeclarationScope(); | 2317 Scope* declaration_scope = scope_->DeclarationScope(); |
| 2305 if (declaration_scope->is_global_scope() || | 2318 if (declaration_scope->is_global_scope() || |
| 2306 declaration_scope->is_eval_scope()) { | 2319 declaration_scope->is_eval_scope()) { |
| 2307 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2320 Handle<String> message = isolate()->factory()->illegal_return_string(); |
| 2308 Expression* throw_error = | 2321 Expression* throw_error = |
| 2309 NewThrowSyntaxError(message, Handle<Object>::null()); | 2322 NewThrowSyntaxError(message, Handle<Object>::null()); |
| 2310 return factory()->NewExpressionStatement(throw_error, pos); | 2323 return factory()->NewExpressionStatement(throw_error, pos); |
| 2311 } | 2324 } |
| 2312 return result; | 2325 return result; |
| 2313 } | 2326 } |
| 2314 | 2327 |
| 2315 | 2328 |
| 2316 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2329 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2317 // WithStatement :: | 2330 // WithStatement :: |
| 2318 // 'with' '(' Expression ')' Statement | 2331 // 'with' '(' Expression ')' Statement |
| 2319 | 2332 |
| 2320 Expect(Token::WITH, CHECK_OK); | 2333 Expect(Token::WITH, CHECK_OK); |
| 2321 int pos = position(); | 2334 int pos = position(); |
| 2322 | 2335 |
| 2323 if (!top_scope_->is_classic_mode()) { | 2336 if (!scope_->is_classic_mode()) { |
| 2324 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2337 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2325 *ok = false; | 2338 *ok = false; |
| 2326 return NULL; | 2339 return NULL; |
| 2327 } | 2340 } |
| 2328 | 2341 |
| 2329 Expect(Token::LPAREN, CHECK_OK); | 2342 Expect(Token::LPAREN, CHECK_OK); |
| 2330 Expression* expr = ParseExpression(true, CHECK_OK); | 2343 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2331 Expect(Token::RPAREN, CHECK_OK); | 2344 Expect(Token::RPAREN, CHECK_OK); |
| 2332 | 2345 |
| 2333 top_scope_->DeclarationScope()->RecordWithStatement(); | 2346 scope_->DeclarationScope()->RecordWithStatement(); |
| 2334 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2347 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
| 2335 Statement* stmt; | 2348 Statement* stmt; |
| 2336 { BlockState block_state(this, with_scope); | 2349 { BlockState block_state(&scope_, with_scope); |
| 2337 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2350 with_scope->set_start_position(scanner()->peek_location().beg_pos); |
| 2338 stmt = ParseStatement(labels, CHECK_OK); | 2351 stmt = ParseStatement(labels, CHECK_OK); |
| 2339 with_scope->set_end_position(scanner().location().end_pos); | 2352 with_scope->set_end_position(scanner()->location().end_pos); |
| 2340 } | 2353 } |
| 2341 return factory()->NewWithStatement(with_scope, expr, stmt, pos); | 2354 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
| 2342 } | 2355 } |
| 2343 | 2356 |
| 2344 | 2357 |
| 2345 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2358 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2346 // CaseClause :: | 2359 // CaseClause :: |
| 2347 // 'case' Expression ':' Statement* | 2360 // 'case' Expression ':' Statement* |
| 2348 // 'default' ':' Statement* | 2361 // 'default' ':' Statement* |
| 2349 | 2362 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2403 return statement; | 2416 return statement; |
| 2404 } | 2417 } |
| 2405 | 2418 |
| 2406 | 2419 |
| 2407 Statement* Parser::ParseThrowStatement(bool* ok) { | 2420 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2408 // ThrowStatement :: | 2421 // ThrowStatement :: |
| 2409 // 'throw' Expression ';' | 2422 // 'throw' Expression ';' |
| 2410 | 2423 |
| 2411 Expect(Token::THROW, CHECK_OK); | 2424 Expect(Token::THROW, CHECK_OK); |
| 2412 int pos = position(); | 2425 int pos = position(); |
| 2413 if (scanner().HasAnyLineTerminatorBeforeNext()) { | 2426 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2414 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2427 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2415 *ok = false; | 2428 *ok = false; |
| 2416 return NULL; | 2429 return NULL; |
| 2417 } | 2430 } |
| 2418 Expression* exception = ParseExpression(true, CHECK_OK); | 2431 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2419 ExpectSemicolon(CHECK_OK); | 2432 ExpectSemicolon(CHECK_OK); |
| 2420 | 2433 |
| 2421 return factory()->NewExpressionStatement( | 2434 return factory()->NewExpressionStatement( |
| 2422 factory()->NewThrow(exception, pos), pos); | 2435 factory()->NewThrow(exception, pos), pos); |
| 2423 } | 2436 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 // always collect the targets. | 2471 // always collect the targets. |
| 2459 TargetCollector catch_collector(zone()); | 2472 TargetCollector catch_collector(zone()); |
| 2460 Scope* catch_scope = NULL; | 2473 Scope* catch_scope = NULL; |
| 2461 Variable* catch_variable = NULL; | 2474 Variable* catch_variable = NULL; |
| 2462 Block* catch_block = NULL; | 2475 Block* catch_block = NULL; |
| 2463 Handle<String> name; | 2476 Handle<String> name; |
| 2464 if (tok == Token::CATCH) { | 2477 if (tok == Token::CATCH) { |
| 2465 Consume(Token::CATCH); | 2478 Consume(Token::CATCH); |
| 2466 | 2479 |
| 2467 Expect(Token::LPAREN, CHECK_OK); | 2480 Expect(Token::LPAREN, CHECK_OK); |
| 2468 catch_scope = NewScope(top_scope_, CATCH_SCOPE); | 2481 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2469 catch_scope->set_start_position(scanner().location().beg_pos); | 2482 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2470 name = ParseIdentifier(CHECK_OK); | 2483 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2471 | |
| 2472 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 2473 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | |
| 2474 *ok = false; | |
| 2475 return NULL; | |
| 2476 } | |
| 2477 | 2484 |
| 2478 Expect(Token::RPAREN, CHECK_OK); | 2485 Expect(Token::RPAREN, CHECK_OK); |
| 2479 | 2486 |
| 2480 if (peek() == Token::LBRACE) { | 2487 Target target(&this->target_stack_, &catch_collector); |
| 2481 Target target(&this->target_stack_, &catch_collector); | 2488 VariableMode mode = is_extended_mode() ? LET : VAR; |
| 2482 VariableMode mode = is_extended_mode() ? LET : VAR; | 2489 catch_variable = |
| 2483 catch_variable = | 2490 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2484 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | |
| 2485 | 2491 |
| 2486 BlockState block_state(this, catch_scope); | 2492 BlockState block_state(&scope_, catch_scope); |
| 2487 catch_block = ParseBlock(NULL, CHECK_OK); | 2493 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2488 } else { | 2494 |
| 2489 Expect(Token::LBRACE, CHECK_OK); | 2495 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2490 } | |
| 2491 catch_scope->set_end_position(scanner().location().end_pos); | |
| 2492 tok = peek(); | 2496 tok = peek(); |
| 2493 } | 2497 } |
| 2494 | 2498 |
| 2495 Block* finally_block = NULL; | 2499 Block* finally_block = NULL; |
| 2496 if (tok == Token::FINALLY || catch_block == NULL) { | 2500 ASSERT(tok == Token::FINALLY || catch_block != NULL); |
| 2501 if (tok == Token::FINALLY) { |
| 2497 Consume(Token::FINALLY); | 2502 Consume(Token::FINALLY); |
| 2498 finally_block = ParseBlock(NULL, CHECK_OK); | 2503 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2499 } | 2504 } |
| 2500 | 2505 |
| 2501 // Simplify the AST nodes by converting: | 2506 // Simplify the AST nodes by converting: |
| 2502 // 'try B0 catch B1 finally B2' | 2507 // 'try B0 catch B1 finally B2' |
| 2503 // to: | 2508 // to: |
| 2504 // 'try { try B0 catch B1 } finally B2' | 2509 // 'try { try B0 catch B1 } finally B2' |
| 2505 | 2510 |
| 2506 if (catch_block != NULL && finally_block != NULL) { | 2511 if (catch_block != NULL && finally_block != NULL) { |
| 2507 // If we have both, create an inner try/catch. | 2512 // If we have both, create an inner try/catch. |
| 2508 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2513 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2509 int index = current_function_state_->NextHandlerIndex(); | 2514 int index = function_state_->NextHandlerIndex(); |
| 2510 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2515 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
| 2511 index, try_block, catch_scope, catch_variable, catch_block, | 2516 index, try_block, catch_scope, catch_variable, catch_block, |
| 2512 RelocInfo::kNoPosition); | 2517 RelocInfo::kNoPosition); |
| 2513 statement->set_escaping_targets(try_collector.targets()); | 2518 statement->set_escaping_targets(try_collector.targets()); |
| 2514 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 2519 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 2515 try_block->AddStatement(statement, zone()); | 2520 try_block->AddStatement(statement, zone()); |
| 2516 catch_block = NULL; // Clear to indicate it's been handled. | 2521 catch_block = NULL; // Clear to indicate it's been handled. |
| 2517 } | 2522 } |
| 2518 | 2523 |
| 2519 TryStatement* result = NULL; | 2524 TryStatement* result = NULL; |
| 2520 if (catch_block != NULL) { | 2525 if (catch_block != NULL) { |
| 2521 ASSERT(finally_block == NULL); | 2526 ASSERT(finally_block == NULL); |
| 2522 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2527 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2523 int index = current_function_state_->NextHandlerIndex(); | 2528 int index = function_state_->NextHandlerIndex(); |
| 2524 result = factory()->NewTryCatchStatement( | 2529 result = factory()->NewTryCatchStatement( |
| 2525 index, try_block, catch_scope, catch_variable, catch_block, pos); | 2530 index, try_block, catch_scope, catch_variable, catch_block, pos); |
| 2526 } else { | 2531 } else { |
| 2527 ASSERT(finally_block != NULL); | 2532 ASSERT(finally_block != NULL); |
| 2528 int index = current_function_state_->NextHandlerIndex(); | 2533 int index = function_state_->NextHandlerIndex(); |
| 2529 result = factory()->NewTryFinallyStatement( | 2534 result = factory()->NewTryFinallyStatement( |
| 2530 index, try_block, finally_block, pos); | 2535 index, try_block, finally_block, pos); |
| 2531 // Combine the jump targets of the try block and the possible catch block. | 2536 // Combine the jump targets of the try block and the possible catch block. |
| 2532 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2537 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2533 } | 2538 } |
| 2534 | 2539 |
| 2535 result->set_escaping_targets(try_collector.targets()); | 2540 result->set_escaping_targets(try_collector.targets()); |
| 2536 return result; | 2541 return result; |
| 2537 } | 2542 } |
| 2538 | 2543 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 | 2603 |
| 2599 | 2604 |
| 2600 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2605 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2601 Expression* each, | 2606 Expression* each, |
| 2602 Expression* subject, | 2607 Expression* subject, |
| 2603 Statement* body) { | 2608 Statement* body) { |
| 2604 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2609 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2605 | 2610 |
| 2606 if (for_of != NULL) { | 2611 if (for_of != NULL) { |
| 2607 Factory* heap_factory = isolate()->factory(); | 2612 Factory* heap_factory = isolate()->factory(); |
| 2608 Variable* iterator = top_scope_->DeclarationScope()->NewTemporary( | 2613 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
| 2609 heap_factory->dot_iterator_string()); | 2614 heap_factory->dot_iterator_string()); |
| 2610 Variable* result = top_scope_->DeclarationScope()->NewTemporary( | 2615 Variable* result = scope_->DeclarationScope()->NewTemporary( |
| 2611 heap_factory->dot_result_string()); | 2616 heap_factory->dot_result_string()); |
| 2612 | 2617 |
| 2613 Expression* assign_iterator; | 2618 Expression* assign_iterator; |
| 2614 Expression* next_result; | 2619 Expression* next_result; |
| 2615 Expression* result_done; | 2620 Expression* result_done; |
| 2616 Expression* assign_each; | 2621 Expression* assign_each; |
| 2617 | 2622 |
| 2618 // var iterator = iterable; | 2623 // var iterator = iterable; |
| 2619 { | 2624 { |
| 2620 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2625 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2667 | 2672 |
| 2668 | 2673 |
| 2669 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2674 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2670 // ForStatement :: | 2675 // ForStatement :: |
| 2671 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2676 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2672 | 2677 |
| 2673 int pos = peek_position(); | 2678 int pos = peek_position(); |
| 2674 Statement* init = NULL; | 2679 Statement* init = NULL; |
| 2675 | 2680 |
| 2676 // Create an in-between scope for let-bound iteration variables. | 2681 // Create an in-between scope for let-bound iteration variables. |
| 2677 Scope* saved_scope = top_scope_; | 2682 Scope* saved_scope = scope_; |
| 2678 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2683 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 2679 top_scope_ = for_scope; | 2684 scope_ = for_scope; |
| 2680 | 2685 |
| 2681 Expect(Token::FOR, CHECK_OK); | 2686 Expect(Token::FOR, CHECK_OK); |
| 2682 Expect(Token::LPAREN, CHECK_OK); | 2687 Expect(Token::LPAREN, CHECK_OK); |
| 2683 for_scope->set_start_position(scanner().location().beg_pos); | 2688 for_scope->set_start_position(scanner()->location().beg_pos); |
| 2684 if (peek() != Token::SEMICOLON) { | 2689 if (peek() != Token::SEMICOLON) { |
| 2685 if (peek() == Token::VAR || peek() == Token::CONST) { | 2690 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2686 bool is_const = peek() == Token::CONST; | 2691 bool is_const = peek() == Token::CONST; |
| 2687 Handle<String> name; | 2692 Handle<String> name; |
| 2688 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2693 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2689 Block* variable_statement = | 2694 Block* variable_statement = |
| 2690 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2695 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2691 CHECK_OK); | 2696 CHECK_OK); |
| 2692 bool accept_OF = decl_props == kHasNoInitializers; | 2697 bool accept_OF = decl_props == kHasNoInitializers; |
| 2693 ForEachStatement::VisitMode mode; | 2698 ForEachStatement::VisitMode mode; |
| 2694 | 2699 |
| 2695 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2700 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
| 2696 Interface* interface = | 2701 Interface* interface = |
| 2697 is_const ? Interface::NewConst() : Interface::NewValue(); | 2702 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2698 ForEachStatement* loop = | 2703 ForEachStatement* loop = |
| 2699 factory()->NewForEachStatement(mode, labels, pos); | 2704 factory()->NewForEachStatement(mode, labels, pos); |
| 2700 Target target(&this->target_stack_, loop); | 2705 Target target(&this->target_stack_, loop); |
| 2701 | 2706 |
| 2702 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2707 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2703 Expect(Token::RPAREN, CHECK_OK); | 2708 Expect(Token::RPAREN, CHECK_OK); |
| 2704 | 2709 |
| 2705 VariableProxy* each = | 2710 VariableProxy* each = |
| 2706 top_scope_->NewUnresolved(factory(), name, interface); | 2711 scope_->NewUnresolved(factory(), name, interface); |
| 2707 Statement* body = ParseStatement(NULL, CHECK_OK); | 2712 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2708 InitializeForEachStatement(loop, each, enumerable, body); | 2713 InitializeForEachStatement(loop, each, enumerable, body); |
| 2709 Block* result = | 2714 Block* result = |
| 2710 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2715 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2711 result->AddStatement(variable_statement, zone()); | 2716 result->AddStatement(variable_statement, zone()); |
| 2712 result->AddStatement(loop, zone()); | 2717 result->AddStatement(loop, zone()); |
| 2713 top_scope_ = saved_scope; | 2718 scope_ = saved_scope; |
| 2714 for_scope->set_end_position(scanner().location().end_pos); | 2719 for_scope->set_end_position(scanner()->location().end_pos); |
| 2715 for_scope = for_scope->FinalizeBlockScope(); | 2720 for_scope = for_scope->FinalizeBlockScope(); |
| 2716 ASSERT(for_scope == NULL); | 2721 ASSERT(for_scope == NULL); |
| 2717 // Parsed for-in loop w/ variable/const declaration. | 2722 // Parsed for-in loop w/ variable/const declaration. |
| 2718 return result; | 2723 return result; |
| 2719 } else { | 2724 } else { |
| 2720 init = variable_statement; | 2725 init = variable_statement; |
| 2721 } | 2726 } |
| 2722 } else if (peek() == Token::LET) { | 2727 } else if (peek() == Token::LET) { |
| 2723 Handle<String> name; | 2728 Handle<String> name; |
| 2724 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2729 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2742 // x = x'; | 2747 // x = x'; |
| 2743 // b; | 2748 // b; |
| 2744 // } | 2749 // } |
| 2745 | 2750 |
| 2746 // TODO(keuchel): Move the temporary variable to the block scope, after | 2751 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2747 // implementing stack allocated block scoped variables. | 2752 // implementing stack allocated block scoped variables. |
| 2748 Factory* heap_factory = isolate()->factory(); | 2753 Factory* heap_factory = isolate()->factory(); |
| 2749 Handle<String> tempstr = | 2754 Handle<String> tempstr = |
| 2750 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2755 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
| 2751 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2756 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
| 2752 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2757 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); |
| 2753 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2758 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2754 ForEachStatement* loop = | 2759 ForEachStatement* loop = |
| 2755 factory()->NewForEachStatement(mode, labels, pos); | 2760 factory()->NewForEachStatement(mode, labels, pos); |
| 2756 Target target(&this->target_stack_, loop); | 2761 Target target(&this->target_stack_, loop); |
| 2757 | 2762 |
| 2758 // The expression does not see the loop variable. | 2763 // The expression does not see the loop variable. |
| 2759 top_scope_ = saved_scope; | 2764 scope_ = saved_scope; |
| 2760 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2765 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2761 top_scope_ = for_scope; | 2766 scope_ = for_scope; |
| 2762 Expect(Token::RPAREN, CHECK_OK); | 2767 Expect(Token::RPAREN, CHECK_OK); |
| 2763 | 2768 |
| 2764 VariableProxy* each = | 2769 VariableProxy* each = |
| 2765 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2770 scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
| 2766 Statement* body = ParseStatement(NULL, CHECK_OK); | 2771 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2767 Block* body_block = | 2772 Block* body_block = |
| 2768 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 2773 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 2769 Assignment* assignment = factory()->NewAssignment( | 2774 Assignment* assignment = factory()->NewAssignment( |
| 2770 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2775 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
| 2771 Statement* assignment_statement = factory()->NewExpressionStatement( | 2776 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2772 assignment, RelocInfo::kNoPosition); | 2777 assignment, RelocInfo::kNoPosition); |
| 2773 body_block->AddStatement(variable_statement, zone()); | 2778 body_block->AddStatement(variable_statement, zone()); |
| 2774 body_block->AddStatement(assignment_statement, zone()); | 2779 body_block->AddStatement(assignment_statement, zone()); |
| 2775 body_block->AddStatement(body, zone()); | 2780 body_block->AddStatement(body, zone()); |
| 2776 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2781 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| 2777 top_scope_ = saved_scope; | 2782 scope_ = saved_scope; |
| 2778 for_scope->set_end_position(scanner().location().end_pos); | 2783 for_scope->set_end_position(scanner()->location().end_pos); |
| 2779 for_scope = for_scope->FinalizeBlockScope(); | 2784 for_scope = for_scope->FinalizeBlockScope(); |
| 2780 body_block->set_scope(for_scope); | 2785 body_block->set_scope(for_scope); |
| 2781 // Parsed for-in loop w/ let declaration. | 2786 // Parsed for-in loop w/ let declaration. |
| 2782 return loop; | 2787 return loop; |
| 2783 | 2788 |
| 2784 } else { | 2789 } else { |
| 2785 init = variable_statement; | 2790 init = variable_statement; |
| 2786 } | 2791 } |
| 2787 } else { | 2792 } else { |
| 2788 Expression* expression = ParseExpression(false, CHECK_OK); | 2793 Expression* expression = ParseExpression(false, CHECK_OK); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2801 } | 2806 } |
| 2802 ForEachStatement* loop = | 2807 ForEachStatement* loop = |
| 2803 factory()->NewForEachStatement(mode, labels, pos); | 2808 factory()->NewForEachStatement(mode, labels, pos); |
| 2804 Target target(&this->target_stack_, loop); | 2809 Target target(&this->target_stack_, loop); |
| 2805 | 2810 |
| 2806 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2811 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2807 Expect(Token::RPAREN, CHECK_OK); | 2812 Expect(Token::RPAREN, CHECK_OK); |
| 2808 | 2813 |
| 2809 Statement* body = ParseStatement(NULL, CHECK_OK); | 2814 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2810 InitializeForEachStatement(loop, expression, enumerable, body); | 2815 InitializeForEachStatement(loop, expression, enumerable, body); |
| 2811 top_scope_ = saved_scope; | 2816 scope_ = saved_scope; |
| 2812 for_scope->set_end_position(scanner().location().end_pos); | 2817 for_scope->set_end_position(scanner()->location().end_pos); |
| 2813 for_scope = for_scope->FinalizeBlockScope(); | 2818 for_scope = for_scope->FinalizeBlockScope(); |
| 2814 ASSERT(for_scope == NULL); | 2819 ASSERT(for_scope == NULL); |
| 2815 // Parsed for-in loop. | 2820 // Parsed for-in loop. |
| 2816 return loop; | 2821 return loop; |
| 2817 | 2822 |
| 2818 } else { | 2823 } else { |
| 2819 init = factory()->NewExpressionStatement( | 2824 init = factory()->NewExpressionStatement( |
| 2820 expression, RelocInfo::kNoPosition); | 2825 expression, RelocInfo::kNoPosition); |
| 2821 } | 2826 } |
| 2822 } | 2827 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2836 Expect(Token::SEMICOLON, CHECK_OK); | 2841 Expect(Token::SEMICOLON, CHECK_OK); |
| 2837 | 2842 |
| 2838 Statement* next = NULL; | 2843 Statement* next = NULL; |
| 2839 if (peek() != Token::RPAREN) { | 2844 if (peek() != Token::RPAREN) { |
| 2840 Expression* exp = ParseExpression(true, CHECK_OK); | 2845 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2841 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); | 2846 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
| 2842 } | 2847 } |
| 2843 Expect(Token::RPAREN, CHECK_OK); | 2848 Expect(Token::RPAREN, CHECK_OK); |
| 2844 | 2849 |
| 2845 Statement* body = ParseStatement(NULL, CHECK_OK); | 2850 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2846 top_scope_ = saved_scope; | 2851 scope_ = saved_scope; |
| 2847 for_scope->set_end_position(scanner().location().end_pos); | 2852 for_scope->set_end_position(scanner()->location().end_pos); |
| 2848 for_scope = for_scope->FinalizeBlockScope(); | 2853 for_scope = for_scope->FinalizeBlockScope(); |
| 2849 if (for_scope != NULL) { | 2854 if (for_scope != NULL) { |
| 2850 // Rewrite a for statement of the form | 2855 // Rewrite a for statement of the form |
| 2851 // | 2856 // |
| 2852 // for (let x = i; c; n) b | 2857 // for (let x = i; c; n) b |
| 2853 // | 2858 // |
| 2854 // into | 2859 // into |
| 2855 // | 2860 // |
| 2856 // { | 2861 // { |
| 2857 // let x = i; | 2862 // let x = i; |
| 2858 // for (; c; n) b | 2863 // for (; c; n) b |
| 2859 // } | 2864 // } |
| 2860 ASSERT(init != NULL); | 2865 ASSERT(init != NULL); |
| 2861 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2866 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2862 result->AddStatement(init, zone()); | 2867 result->AddStatement(init, zone()); |
| 2863 result->AddStatement(loop, zone()); | 2868 result->AddStatement(loop, zone()); |
| 2864 result->set_scope(for_scope); | 2869 result->set_scope(for_scope); |
| 2865 loop->Initialize(NULL, cond, next, body); | 2870 loop->Initialize(NULL, cond, next, body); |
| 2866 return result; | 2871 return result; |
| 2867 } else { | 2872 } else { |
| 2868 loop->Initialize(init, cond, next, body); | 2873 loop->Initialize(init, cond, next, body); |
| 2869 return loop; | 2874 return loop; |
| 2870 } | 2875 } |
| 2871 } | 2876 } |
| 2872 | 2877 |
| 2873 | 2878 |
| 2874 // Precedence = 1 | |
| 2875 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | |
| 2876 // Expression :: | |
| 2877 // AssignmentExpression | |
| 2878 // Expression ',' AssignmentExpression | |
| 2879 | |
| 2880 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | |
| 2881 while (peek() == Token::COMMA) { | |
| 2882 Expect(Token::COMMA, CHECK_OK); | |
| 2883 int pos = position(); | |
| 2884 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | |
| 2885 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | |
| 2886 } | |
| 2887 return result; | |
| 2888 } | |
| 2889 | |
| 2890 | |
| 2891 // Precedence = 2 | 2879 // Precedence = 2 |
| 2892 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2880 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2893 // AssignmentExpression :: | 2881 // AssignmentExpression :: |
| 2894 // ConditionalExpression | 2882 // ConditionalExpression |
| 2895 // YieldExpression | 2883 // YieldExpression |
| 2896 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2884 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2897 | 2885 |
| 2898 if (peek() == Token::YIELD && is_generator()) { | 2886 if (peek() == Token::YIELD && is_generator()) { |
| 2899 return ParseYieldExpression(ok); | 2887 return ParseYieldExpression(ok); |
| 2900 } | 2888 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2912 // side expression. We could report this as a syntax error here but | 2900 // side expression. We could report this as a syntax error here but |
| 2913 // for compatibility with JSC we choose to report the error at | 2901 // for compatibility with JSC we choose to report the error at |
| 2914 // runtime. | 2902 // runtime. |
| 2915 // TODO(ES5): Should change parsing for spec conformance. | 2903 // TODO(ES5): Should change parsing for spec conformance. |
| 2916 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2904 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2917 Handle<String> message = | 2905 Handle<String> message = |
| 2918 isolate()->factory()->invalid_lhs_in_assignment_string(); | 2906 isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 2919 expression = NewThrowReferenceError(message); | 2907 expression = NewThrowReferenceError(message); |
| 2920 } | 2908 } |
| 2921 | 2909 |
| 2922 if (!top_scope_->is_classic_mode()) { | 2910 if (!scope_->is_classic_mode()) { |
| 2923 // Assignment to eval or arguments is disallowed in strict mode. | 2911 // Assignment to eval or arguments is disallowed in strict mode. |
| 2924 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2912 CheckStrictModeLValue(expression, CHECK_OK); |
| 2925 } | 2913 } |
| 2926 MarkAsLValue(expression); | 2914 MarkAsLValue(expression); |
| 2927 | 2915 |
| 2928 Token::Value op = Next(); // Get assignment operator. | 2916 Token::Value op = Next(); // Get assignment operator. |
| 2929 int pos = position(); | 2917 int pos = position(); |
| 2930 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2918 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2931 | 2919 |
| 2932 // TODO(1231235): We try to estimate the set of properties set by | 2920 // TODO(1231235): We try to estimate the set of properties set by |
| 2933 // constructors. We define a new property whenever there is an | 2921 // constructors. We define a new property whenever there is an |
| 2934 // assignment to a property of 'this'. We should probably only add | 2922 // assignment to a property of 'this'. We should probably only add |
| 2935 // properties if we haven't seen them before. Otherwise we'll | 2923 // properties if we haven't seen them before. Otherwise we'll |
| 2936 // probably overestimate the number of properties. | 2924 // probably overestimate the number of properties. |
| 2937 Property* property = expression ? expression->AsProperty() : NULL; | 2925 Property* property = expression ? expression->AsProperty() : NULL; |
| 2938 if (op == Token::ASSIGN && | 2926 if (op == Token::ASSIGN && |
| 2939 property != NULL && | 2927 property != NULL && |
| 2940 property->obj()->AsVariableProxy() != NULL && | 2928 property->obj()->AsVariableProxy() != NULL && |
| 2941 property->obj()->AsVariableProxy()->is_this()) { | 2929 property->obj()->AsVariableProxy()->is_this()) { |
| 2942 current_function_state_->AddProperty(); | 2930 function_state_->AddProperty(); |
| 2943 } | 2931 } |
| 2944 | 2932 |
| 2945 // If we assign a function literal to a property we pretenure the | 2933 // If we assign a function literal to a property we pretenure the |
| 2946 // literal so it can be added as a constant function property. | 2934 // literal so it can be added as a constant function property. |
| 2947 if (property != NULL && right->AsFunctionLiteral() != NULL) { | 2935 if (property != NULL && right->AsFunctionLiteral() != NULL) { |
| 2948 right->AsFunctionLiteral()->set_pretenure(); | 2936 right->AsFunctionLiteral()->set_pretenure(); |
| 2949 } | 2937 } |
| 2950 | 2938 |
| 2951 if (fni_ != NULL) { | 2939 if (fni_ != NULL) { |
| 2952 // Check if the right hand side is a call to avoid inferring a | 2940 // Check if the right hand side is a call to avoid inferring a |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2968 | 2956 |
| 2969 | 2957 |
| 2970 Expression* Parser::ParseYieldExpression(bool* ok) { | 2958 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 2971 // YieldExpression :: | 2959 // YieldExpression :: |
| 2972 // 'yield' '*'? AssignmentExpression | 2960 // 'yield' '*'? AssignmentExpression |
| 2973 int pos = peek_position(); | 2961 int pos = peek_position(); |
| 2974 Expect(Token::YIELD, CHECK_OK); | 2962 Expect(Token::YIELD, CHECK_OK); |
| 2975 Yield::Kind kind = | 2963 Yield::Kind kind = |
| 2976 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2964 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 2977 Expression* generator_object = factory()->NewVariableProxy( | 2965 Expression* generator_object = factory()->NewVariableProxy( |
| 2978 current_function_state_->generator_object_variable()); | 2966 function_state_->generator_object_variable()); |
| 2979 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 2967 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| 2980 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); | 2968 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
| 2981 if (kind == Yield::DELEGATING) { | 2969 if (kind == Yield::DELEGATING) { |
| 2982 yield->set_index(current_function_state_->NextHandlerIndex()); | 2970 yield->set_index(function_state_->NextHandlerIndex()); |
| 2983 } | 2971 } |
| 2984 return yield; | 2972 return yield; |
| 2985 } | 2973 } |
| 2986 | 2974 |
| 2987 | 2975 |
| 2988 // Precedence = 3 | 2976 // Precedence = 3 |
| 2989 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2977 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 2990 // ConditionalExpression :: | 2978 // ConditionalExpression :: |
| 2991 // LogicalOrExpression | 2979 // LogicalOrExpression |
| 2992 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2980 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2993 | 2981 |
| 2994 int pos = peek_position(); | 2982 int pos = peek_position(); |
| 2995 // We start using the binary expression parser for prec >= 4 only! | 2983 // We start using the binary expression parser for prec >= 4 only! |
| 2996 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2984 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2997 if (peek() != Token::CONDITIONAL) return expression; | 2985 if (peek() != Token::CONDITIONAL) return expression; |
| 2998 Consume(Token::CONDITIONAL); | 2986 Consume(Token::CONDITIONAL); |
| 2999 // In parsing the first assignment expression in conditional | 2987 // In parsing the first assignment expression in conditional |
| 3000 // expressions we always accept the 'in' keyword; see ECMA-262, | 2988 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3001 // section 11.12, page 58. | 2989 // section 11.12, page 58. |
| 3002 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 2990 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 3003 Expect(Token::COLON, CHECK_OK); | 2991 Expect(Token::COLON, CHECK_OK); |
| 3004 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2992 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 3005 return factory()->NewConditional(expression, left, right, pos); | 2993 return factory()->NewConditional(expression, left, right, pos); |
| 3006 } | 2994 } |
| 3007 | 2995 |
| 3008 | 2996 |
| 3009 int ParserBase::Precedence(Token::Value tok, bool accept_IN) { | |
| 3010 if (tok == Token::IN && !accept_IN) | |
| 3011 return 0; // 0 precedence will terminate binary expression parsing | |
| 3012 | |
| 3013 return Token::Precedence(tok); | |
| 3014 } | |
| 3015 | |
| 3016 | |
| 3017 // Precedence >= 4 | 2997 // Precedence >= 4 |
| 3018 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2998 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 3019 ASSERT(prec >= 4); | 2999 ASSERT(prec >= 4); |
| 3020 Expression* x = ParseUnaryExpression(CHECK_OK); | 3000 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 3021 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3001 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3022 // prec1 >= 4 | 3002 // prec1 >= 4 |
| 3023 while (Precedence(peek(), accept_IN) == prec1) { | 3003 while (Precedence(peek(), accept_IN) == prec1) { |
| 3024 Token::Value op = Next(); | 3004 Token::Value op = Next(); |
| 3025 int pos = position(); | 3005 int pos = position(); |
| 3026 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3006 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3144 return factory()->NewNumberLiteral(-value, pos); | 3124 return factory()->NewNumberLiteral(-value, pos); |
| 3145 case Token::BIT_NOT: | 3125 case Token::BIT_NOT: |
| 3146 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); | 3126 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 3147 default: | 3127 default: |
| 3148 break; | 3128 break; |
| 3149 } | 3129 } |
| 3150 } | 3130 } |
| 3151 } | 3131 } |
| 3152 | 3132 |
| 3153 // "delete identifier" is a syntax error in strict mode. | 3133 // "delete identifier" is a syntax error in strict mode. |
| 3154 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { | 3134 if (op == Token::DELETE && !scope_->is_classic_mode()) { |
| 3155 VariableProxy* operand = expression->AsVariableProxy(); | 3135 VariableProxy* operand = expression->AsVariableProxy(); |
| 3156 if (operand != NULL && !operand->is_this()) { | 3136 if (operand != NULL && !operand->is_this()) { |
| 3157 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3137 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 3158 *ok = false; | 3138 *ok = false; |
| 3159 return NULL; | 3139 return NULL; |
| 3160 } | 3140 } |
| 3161 } | 3141 } |
| 3162 | 3142 |
| 3163 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3143 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
| 3164 // without any special stub and the multiplication is removed later in | 3144 // without any special stub and the multiplication is removed later in |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3192 // Signal a reference error if the expression is an invalid | 3172 // Signal a reference error if the expression is an invalid |
| 3193 // left-hand side expression. We could report this as a syntax | 3173 // left-hand side expression. We could report this as a syntax |
| 3194 // error here but for compatibility with JSC we choose to report the | 3174 // error here but for compatibility with JSC we choose to report the |
| 3195 // error at runtime. | 3175 // error at runtime. |
| 3196 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3176 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3197 Handle<String> message = | 3177 Handle<String> message = |
| 3198 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3178 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3199 expression = NewThrowReferenceError(message); | 3179 expression = NewThrowReferenceError(message); |
| 3200 } | 3180 } |
| 3201 | 3181 |
| 3202 if (!top_scope_->is_classic_mode()) { | 3182 if (!scope_->is_classic_mode()) { |
| 3203 // Prefix expression operand in strict mode may not be eval or arguments. | 3183 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3204 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3184 CheckStrictModeLValue(expression, CHECK_OK); |
| 3205 } | 3185 } |
| 3206 MarkAsLValue(expression); | 3186 MarkAsLValue(expression); |
| 3207 | 3187 |
| 3208 return factory()->NewCountOperation(op, | 3188 return factory()->NewCountOperation(op, |
| 3209 true /* prefix */, | 3189 true /* prefix */, |
| 3210 expression, | 3190 expression, |
| 3211 position()); | 3191 position()); |
| 3212 | 3192 |
| 3213 } else { | 3193 } else { |
| 3214 return ParsePostfixExpression(ok); | 3194 return ParsePostfixExpression(ok); |
| 3215 } | 3195 } |
| 3216 } | 3196 } |
| 3217 | 3197 |
| 3218 | 3198 |
| 3219 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3199 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 3220 // PostfixExpression :: | 3200 // PostfixExpression :: |
| 3221 // LeftHandSideExpression ('++' | '--')? | 3201 // LeftHandSideExpression ('++' | '--')? |
| 3222 | 3202 |
| 3223 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 3203 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 3224 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 3204 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 3225 Token::IsCountOp(peek())) { | 3205 Token::IsCountOp(peek())) { |
| 3226 // Signal a reference error if the expression is an invalid | 3206 // Signal a reference error if the expression is an invalid |
| 3227 // left-hand side expression. We could report this as a syntax | 3207 // left-hand side expression. We could report this as a syntax |
| 3228 // error here but for compatibility with JSC we choose to report the | 3208 // error here but for compatibility with JSC we choose to report the |
| 3229 // error at runtime. | 3209 // error at runtime. |
| 3230 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3210 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3231 Handle<String> message = | 3211 Handle<String> message = |
| 3232 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3212 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3233 expression = NewThrowReferenceError(message); | 3213 expression = NewThrowReferenceError(message); |
| 3234 } | 3214 } |
| 3235 | 3215 |
| 3236 if (!top_scope_->is_classic_mode()) { | 3216 if (!scope_->is_classic_mode()) { |
| 3237 // Postfix expression operand in strict mode may not be eval or arguments. | 3217 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3238 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3218 CheckStrictModeLValue(expression, CHECK_OK); |
| 3239 } | 3219 } |
| 3240 MarkAsLValue(expression); | 3220 MarkAsLValue(expression); |
| 3241 | 3221 |
| 3242 Token::Value next = Next(); | 3222 Token::Value next = Next(); |
| 3243 expression = | 3223 expression = |
| 3244 factory()->NewCountOperation(next, | 3224 factory()->NewCountOperation(next, |
| 3245 false /* postfix */, | 3225 false /* postfix */, |
| 3246 expression, | 3226 expression, |
| 3247 position()); | 3227 position()); |
| 3248 } | 3228 } |
| 3249 return expression; | 3229 return expression; |
| 3250 } | 3230 } |
| 3251 | 3231 |
| 3252 | 3232 |
| 3253 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 3233 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 3254 // LeftHandSideExpression :: | 3234 // LeftHandSideExpression :: |
| 3255 // (NewExpression | MemberExpression) ... | 3235 // (NewExpression | MemberExpression) ... |
| 3256 | 3236 |
| 3257 Expression* result; | 3237 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 3258 if (peek() == Token::NEW) { | |
| 3259 result = ParseNewExpression(CHECK_OK); | |
| 3260 } else { | |
| 3261 result = ParseMemberExpression(CHECK_OK); | |
| 3262 } | |
| 3263 | 3238 |
| 3264 while (true) { | 3239 while (true) { |
| 3265 switch (peek()) { | 3240 switch (peek()) { |
| 3266 case Token::LBRACK: { | 3241 case Token::LBRACK: { |
| 3267 Consume(Token::LBRACK); | 3242 Consume(Token::LBRACK); |
| 3268 int pos = position(); | 3243 int pos = position(); |
| 3269 Expression* index = ParseExpression(true, CHECK_OK); | 3244 Expression* index = ParseExpression(true, CHECK_OK); |
| 3270 result = factory()->NewProperty(result, index, pos); | 3245 result = factory()->NewProperty(result, index, pos); |
| 3271 Expect(Token::RBRACK, CHECK_OK); | 3246 Expect(Token::RBRACK, CHECK_OK); |
| 3272 break; | 3247 break; |
| 3273 } | 3248 } |
| 3274 | 3249 |
| 3275 case Token::LPAREN: { | 3250 case Token::LPAREN: { |
| 3276 int pos; | 3251 int pos; |
| 3277 if (scanner().current_token() == Token::IDENTIFIER) { | 3252 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3278 // For call of an identifier we want to report position of | 3253 // For call of an identifier we want to report position of |
| 3279 // the identifier as position of the call in the stack trace. | 3254 // the identifier as position of the call in the stack trace. |
| 3280 pos = position(); | 3255 pos = position(); |
| 3281 } else { | 3256 } else { |
| 3282 // For other kinds of calls we record position of the parenthesis as | 3257 // For other kinds of calls we record position of the parenthesis as |
| 3283 // position of the call. Note that this is extremely important for | 3258 // position of the call. Note that this is extremely important for |
| 3284 // expressions of the form function(){...}() for which call position | 3259 // expressions of the form function(){...}() for which call position |
| 3285 // should not point to the closing brace otherwise it will intersect | 3260 // should not point to the closing brace otherwise it will intersect |
| 3286 // with positions recorded for function literal and confuse debugger. | 3261 // with positions recorded for function literal and confuse debugger. |
| 3287 pos = peek_position(); | 3262 pos = peek_position(); |
| 3288 // Also the trailing parenthesis are a hint that the function will | 3263 // Also the trailing parenthesis are a hint that the function will |
| 3289 // be called immediately. If we happen to have parsed a preceding | 3264 // be called immediately. If we happen to have parsed a preceding |
| 3290 // function literal eagerly, we can also compile it eagerly. | 3265 // function literal eagerly, we can also compile it eagerly. |
| 3291 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3266 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3292 result->AsFunctionLiteral()->set_parenthesized(); | 3267 result->AsFunctionLiteral()->set_parenthesized(); |
| 3293 } | 3268 } |
| 3294 } | 3269 } |
| 3295 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3270 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3296 | 3271 |
| 3297 // Keep track of eval() calls since they disable all local variable | 3272 // Keep track of eval() calls since they disable all local variable |
| 3298 // optimizations. | 3273 // optimizations. |
| 3299 // The calls that need special treatment are the | 3274 // The calls that need special treatment are the |
| 3300 // direct eval calls. These calls are all of the form eval(...), with | 3275 // direct eval calls. These calls are all of the form eval(...), with |
| 3301 // no explicit receiver. | 3276 // no explicit receiver. |
| 3302 // These calls are marked as potentially direct eval calls. Whether | 3277 // These calls are marked as potentially direct eval calls. Whether |
| 3303 // they are actually direct calls to eval is determined at run time. | 3278 // they are actually direct calls to eval is determined at run time. |
| 3304 VariableProxy* callee = result->AsVariableProxy(); | 3279 VariableProxy* callee = result->AsVariableProxy(); |
| 3305 if (callee != NULL && | 3280 if (callee != NULL && |
| 3306 callee->IsVariable(isolate()->factory()->eval_string())) { | 3281 callee->IsVariable(isolate()->factory()->eval_string())) { |
| 3307 top_scope_->DeclarationScope()->RecordEvalCall(); | 3282 scope_->DeclarationScope()->RecordEvalCall(); |
| 3308 } | 3283 } |
| 3309 result = factory()->NewCall(result, args, pos); | 3284 result = factory()->NewCall(result, args, pos); |
| 3310 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3285 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3311 break; | 3286 break; |
| 3312 } | 3287 } |
| 3313 | 3288 |
| 3314 case Token::PERIOD: { | 3289 case Token::PERIOD: { |
| 3315 Consume(Token::PERIOD); | 3290 Consume(Token::PERIOD); |
| 3316 int pos = position(); | 3291 int pos = position(); |
| 3317 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3292 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3318 result = factory()->NewProperty( | 3293 result = factory()->NewProperty( |
| 3319 result, factory()->NewLiteral(name, pos), pos); | 3294 result, factory()->NewLiteral(name, pos), pos); |
| 3320 if (fni_ != NULL) fni_->PushLiteralName(name); | 3295 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3321 break; | 3296 break; |
| 3322 } | 3297 } |
| 3323 | 3298 |
| 3324 default: | 3299 default: |
| 3325 return result; | 3300 return result; |
| 3326 } | 3301 } |
| 3327 } | 3302 } |
| 3328 } | 3303 } |
| 3329 | 3304 |
| 3330 | 3305 |
| 3331 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { | 3306 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) { |
| 3332 // NewExpression :: | 3307 // NewExpression :: |
| 3333 // ('new')+ MemberExpression | 3308 // ('new')+ MemberExpression |
| 3334 | 3309 |
| 3335 // The grammar for new expressions is pretty warped. The keyword | 3310 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 3336 // 'new' can either be a part of the new expression (where it isn't | 3311 // keywords following each other, and then a MemberExpression. When we see '(' |
| 3337 // followed by an argument list) or a part of the member expression, | 3312 // after the MemberExpression, it's associated with the rightmost unassociated |
| 3338 // where it must be followed by an argument list. To accommodate | 3313 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 3339 // this, we parse the 'new' keywords greedily and keep track of how | 3314 // can also occur without arguments. |
| 3340 // many we have parsed. This information is then passed on to the | |
| 3341 // member expression parser, which is only allowed to match argument | |
| 3342 // lists as long as it has 'new' prefixes left | |
| 3343 Expect(Token::NEW, CHECK_OK); | |
| 3344 PositionStack::Element pos(stack, position()); | |
| 3345 | 3315 |
| 3346 Expression* result; | 3316 // Examples of new expression: |
| 3317 // new foo.bar().baz means (new (foo.bar)()).baz |
| 3318 // new foo()() means (new foo())() |
| 3319 // new new foo()() means (new (new foo())()) |
| 3320 // new new foo means new (new foo) |
| 3321 // new new foo() means new (new foo()) |
| 3322 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 3323 |
| 3347 if (peek() == Token::NEW) { | 3324 if (peek() == Token::NEW) { |
| 3348 result = ParseNewPrefix(stack, CHECK_OK); | 3325 Consume(Token::NEW); |
| 3349 } else { | 3326 int new_pos = position(); |
| 3350 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 3327 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 3328 if (peek() == Token::LPAREN) { |
| 3329 // NewExpression with arguments. |
| 3330 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3331 result = factory()->NewCallNew(result, args, new_pos); |
| 3332 // The expression can still continue with . or [ after the arguments. |
| 3333 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 3334 return result; |
| 3335 } |
| 3336 // NewExpression without arguments. |
| 3337 return factory()->NewCallNew( |
| 3338 result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos); |
| 3351 } | 3339 } |
| 3352 | 3340 // No 'new' keyword. |
| 3353 if (!stack->is_empty()) { | 3341 return ParseMemberExpression(ok); |
| 3354 int last = stack->pop(); | |
| 3355 result = factory()->NewCallNew( | |
| 3356 result, new(zone()) ZoneList<Expression*>(0, zone()), last); | |
| 3357 } | |
| 3358 return result; | |
| 3359 } | |
| 3360 | |
| 3361 | |
| 3362 Expression* Parser::ParseNewExpression(bool* ok) { | |
| 3363 PositionStack stack(ok); | |
| 3364 return ParseNewPrefix(&stack, ok); | |
| 3365 } | 3342 } |
| 3366 | 3343 |
| 3367 | 3344 |
| 3368 Expression* Parser::ParseMemberExpression(bool* ok) { | 3345 Expression* Parser::ParseMemberExpression(bool* ok) { |
| 3369 return ParseMemberWithNewPrefixesExpression(NULL, ok); | |
| 3370 } | |
| 3371 | |
| 3372 | |
| 3373 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, | |
| 3374 bool* ok) { | |
| 3375 // MemberExpression :: | 3346 // MemberExpression :: |
| 3376 // (PrimaryExpression | FunctionLiteral) | 3347 // (PrimaryExpression | FunctionLiteral) |
| 3377 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3348 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3378 | 3349 |
| 3350 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 3351 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 3352 // caller. |
| 3353 |
| 3379 // Parse the initial primary or function expression. | 3354 // Parse the initial primary or function expression. |
| 3380 Expression* result = NULL; | 3355 Expression* result = NULL; |
| 3381 if (peek() == Token::FUNCTION) { | 3356 if (peek() == Token::FUNCTION) { |
| 3382 Expect(Token::FUNCTION, CHECK_OK); | 3357 Consume(Token::FUNCTION); |
| 3383 int function_token_position = position(); | 3358 int function_token_position = position(); |
| 3384 bool is_generator = allow_generators() && Check(Token::MUL); | 3359 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3385 Handle<String> name; | 3360 Handle<String> name; |
| 3386 bool is_strict_reserved_name = false; | 3361 bool is_strict_reserved_name = false; |
| 3362 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3387 if (peek_any_identifier()) { | 3363 if (peek_any_identifier()) { |
| 3388 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3364 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3389 CHECK_OK); | 3365 CHECK_OK); |
| 3366 function_name_location = scanner()->location(); |
| 3390 } | 3367 } |
| 3391 FunctionLiteral::FunctionType function_type = name.is_null() | 3368 FunctionLiteral::FunctionType function_type = name.is_null() |
| 3392 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3369 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3393 : FunctionLiteral::NAMED_EXPRESSION; | 3370 : FunctionLiteral::NAMED_EXPRESSION; |
| 3394 result = ParseFunctionLiteral(name, | 3371 result = ParseFunctionLiteral(name, |
| 3372 function_name_location, |
| 3395 is_strict_reserved_name, | 3373 is_strict_reserved_name, |
| 3396 is_generator, | 3374 is_generator, |
| 3397 function_token_position, | 3375 function_token_position, |
| 3398 function_type, | 3376 function_type, |
| 3399 CHECK_OK); | 3377 CHECK_OK); |
| 3400 } else { | 3378 } else { |
| 3401 result = ParsePrimaryExpression(CHECK_OK); | 3379 result = ParsePrimaryExpression(CHECK_OK); |
| 3402 } | 3380 } |
| 3403 | 3381 |
| 3382 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 3383 return result; |
| 3384 } |
| 3385 |
| 3386 |
| 3387 Expression* Parser::ParseMemberExpressionContinuation(Expression* expression, |
| 3388 bool* ok) { |
| 3389 // Parses this part of MemberExpression: |
| 3390 // ('[' Expression ']' | '.' Identifier)* |
| 3404 while (true) { | 3391 while (true) { |
| 3405 switch (peek()) { | 3392 switch (peek()) { |
| 3406 case Token::LBRACK: { | 3393 case Token::LBRACK: { |
| 3407 Consume(Token::LBRACK); | 3394 Consume(Token::LBRACK); |
| 3408 int pos = position(); | 3395 int pos = position(); |
| 3409 Expression* index = ParseExpression(true, CHECK_OK); | 3396 Expression* index = ParseExpression(true, CHECK_OK); |
| 3410 result = factory()->NewProperty(result, index, pos); | 3397 expression = factory()->NewProperty(expression, index, pos); |
| 3411 if (fni_ != NULL) { | 3398 if (fni_ != NULL) { |
| 3412 if (index->IsPropertyName()) { | 3399 if (index->IsPropertyName()) { |
| 3413 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | 3400 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
| 3414 } else { | 3401 } else { |
| 3415 fni_->PushLiteralName( | 3402 fni_->PushLiteralName( |
| 3416 isolate()->factory()->anonymous_function_string()); | 3403 isolate()->factory()->anonymous_function_string()); |
| 3417 } | 3404 } |
| 3418 } | 3405 } |
| 3419 Expect(Token::RBRACK, CHECK_OK); | 3406 Expect(Token::RBRACK, CHECK_OK); |
| 3420 break; | 3407 break; |
| 3421 } | 3408 } |
| 3422 case Token::PERIOD: { | 3409 case Token::PERIOD: { |
| 3423 Consume(Token::PERIOD); | 3410 Consume(Token::PERIOD); |
| 3424 int pos = position(); | 3411 int pos = position(); |
| 3425 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3412 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3426 result = factory()->NewProperty( | 3413 expression = factory()->NewProperty( |
| 3427 result, factory()->NewLiteral(name, pos), pos); | 3414 expression, factory()->NewLiteral(name, pos), pos); |
| 3428 if (fni_ != NULL) fni_->PushLiteralName(name); | 3415 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3429 break; | 3416 break; |
| 3430 } | 3417 } |
| 3431 case Token::LPAREN: { | |
| 3432 if ((stack == NULL) || stack->is_empty()) return result; | |
| 3433 // Consume one of the new prefixes (already parsed). | |
| 3434 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | |
| 3435 int pos = stack->pop(); | |
| 3436 result = factory()->NewCallNew(result, args, pos); | |
| 3437 break; | |
| 3438 } | |
| 3439 default: | 3418 default: |
| 3440 return result; | 3419 return expression; |
| 3441 } | 3420 } |
| 3442 } | 3421 } |
| 3422 ASSERT(false); |
| 3423 return NULL; |
| 3443 } | 3424 } |
| 3444 | 3425 |
| 3445 | 3426 |
| 3446 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3427 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 3447 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3428 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 3448 // contexts this is used as a statement which invokes the debugger as i a | 3429 // contexts this is used as a statement which invokes the debugger as i a |
| 3449 // break point is present. | 3430 // break point is present. |
| 3450 // DebuggerStatement :: | 3431 // DebuggerStatement :: |
| 3451 // 'debugger' ';' | 3432 // 'debugger' ';' |
| 3452 | 3433 |
| 3453 int pos = peek_position(); | 3434 int pos = peek_position(); |
| 3454 Expect(Token::DEBUGGER, CHECK_OK); | 3435 Expect(Token::DEBUGGER, CHECK_OK); |
| 3455 ExpectSemicolon(CHECK_OK); | 3436 ExpectSemicolon(CHECK_OK); |
| 3456 return factory()->NewDebuggerStatement(pos); | 3437 return factory()->NewDebuggerStatement(pos); |
| 3457 } | 3438 } |
| 3458 | 3439 |
| 3459 | 3440 |
| 3460 void Parser::ReportUnexpectedToken(Token::Value token) { | |
| 3461 // We don't report stack overflows here, to avoid increasing the | |
| 3462 // stack depth even further. Instead we report it after parsing is | |
| 3463 // over, in ParseProgram/ParseJson. | |
| 3464 if (token == Token::ILLEGAL && stack_overflow()) return; | |
| 3465 // Four of the tokens are treated specially | |
| 3466 switch (token) { | |
| 3467 case Token::EOS: | |
| 3468 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | |
| 3469 case Token::NUMBER: | |
| 3470 return ReportMessage("unexpected_token_number", | |
| 3471 Vector<const char*>::empty()); | |
| 3472 case Token::STRING: | |
| 3473 return ReportMessage("unexpected_token_string", | |
| 3474 Vector<const char*>::empty()); | |
| 3475 case Token::IDENTIFIER: | |
| 3476 return ReportMessage("unexpected_token_identifier", | |
| 3477 Vector<const char*>::empty()); | |
| 3478 case Token::FUTURE_RESERVED_WORD: | |
| 3479 return ReportMessage("unexpected_reserved", | |
| 3480 Vector<const char*>::empty()); | |
| 3481 case Token::YIELD: | |
| 3482 case Token::FUTURE_STRICT_RESERVED_WORD: | |
| 3483 return ReportMessage(top_scope_->is_classic_mode() ? | |
| 3484 "unexpected_token_identifier" : | |
| 3485 "unexpected_strict_reserved", | |
| 3486 Vector<const char*>::empty()); | |
| 3487 default: | |
| 3488 const char* name = Token::String(token); | |
| 3489 ASSERT(name != NULL); | |
| 3490 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | |
| 3491 } | |
| 3492 } | |
| 3493 | |
| 3494 | |
| 3495 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 3441 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
| 3496 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 3442 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
| 3497 const char* element[1] = { name_string.get() }; | 3443 const char* element[1] = { name_string.get() }; |
| 3498 ReportMessage("invalid_preparser_data", | 3444 ReportMessage("invalid_preparser_data", |
| 3499 Vector<const char*>(element, 1)); | 3445 Vector<const char*>(element, 1)); |
| 3500 *ok = false; | 3446 *ok = false; |
| 3501 } | 3447 } |
| 3502 | 3448 |
| 3503 | 3449 |
| 3504 Expression* Parser::ParsePrimaryExpression(bool* ok) { | |
| 3505 // PrimaryExpression :: | |
| 3506 // 'this' | |
| 3507 // 'null' | |
| 3508 // 'true' | |
| 3509 // 'false' | |
| 3510 // Identifier | |
| 3511 // Number | |
| 3512 // String | |
| 3513 // ArrayLiteral | |
| 3514 // ObjectLiteral | |
| 3515 // RegExpLiteral | |
| 3516 // '(' Expression ')' | |
| 3517 | |
| 3518 int pos = peek_position(); | |
| 3519 Expression* result = NULL; | |
| 3520 switch (peek()) { | |
| 3521 case Token::THIS: { | |
| 3522 Consume(Token::THIS); | |
| 3523 result = factory()->NewVariableProxy(top_scope_->receiver()); | |
| 3524 break; | |
| 3525 } | |
| 3526 | |
| 3527 case Token::NULL_LITERAL: | |
| 3528 Consume(Token::NULL_LITERAL); | |
| 3529 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); | |
| 3530 break; | |
| 3531 | |
| 3532 case Token::TRUE_LITERAL: | |
| 3533 Consume(Token::TRUE_LITERAL); | |
| 3534 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); | |
| 3535 break; | |
| 3536 | |
| 3537 case Token::FALSE_LITERAL: | |
| 3538 Consume(Token::FALSE_LITERAL); | |
| 3539 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); | |
| 3540 break; | |
| 3541 | |
| 3542 case Token::IDENTIFIER: | |
| 3543 case Token::YIELD: | |
| 3544 case Token::FUTURE_STRICT_RESERVED_WORD: { | |
| 3545 Handle<String> name = ParseIdentifier(CHECK_OK); | |
| 3546 if (fni_ != NULL) fni_->PushVariableName(name); | |
| 3547 // The name may refer to a module instance object, so its type is unknown. | |
| 3548 #ifdef DEBUG | |
| 3549 if (FLAG_print_interface_details) | |
| 3550 PrintF("# Variable %s ", name->ToAsciiArray()); | |
| 3551 #endif | |
| 3552 Interface* interface = Interface::NewUnknown(zone()); | |
| 3553 result = top_scope_->NewUnresolved(factory(), name, interface, pos); | |
| 3554 break; | |
| 3555 } | |
| 3556 | |
| 3557 case Token::NUMBER: { | |
| 3558 Consume(Token::NUMBER); | |
| 3559 ASSERT(scanner().is_literal_ascii()); | |
| 3560 double value = StringToDouble(isolate()->unicode_cache(), | |
| 3561 scanner().literal_ascii_string(), | |
| 3562 ALLOW_HEX | ALLOW_OCTAL | | |
| 3563 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | |
| 3564 result = factory()->NewNumberLiteral(value, pos); | |
| 3565 break; | |
| 3566 } | |
| 3567 | |
| 3568 case Token::STRING: { | |
| 3569 Consume(Token::STRING); | |
| 3570 Handle<String> symbol = GetSymbol(); | |
| 3571 result = factory()->NewLiteral(symbol, pos); | |
| 3572 if (fni_ != NULL) fni_->PushLiteralName(symbol); | |
| 3573 break; | |
| 3574 } | |
| 3575 | |
| 3576 case Token::ASSIGN_DIV: | |
| 3577 result = ParseRegExpLiteral(true, CHECK_OK); | |
| 3578 break; | |
| 3579 | |
| 3580 case Token::DIV: | |
| 3581 result = ParseRegExpLiteral(false, CHECK_OK); | |
| 3582 break; | |
| 3583 | |
| 3584 case Token::LBRACK: | |
| 3585 result = ParseArrayLiteral(CHECK_OK); | |
| 3586 break; | |
| 3587 | |
| 3588 case Token::LBRACE: | |
| 3589 result = ParseObjectLiteral(CHECK_OK); | |
| 3590 break; | |
| 3591 | |
| 3592 case Token::LPAREN: | |
| 3593 Consume(Token::LPAREN); | |
| 3594 // Heuristically try to detect immediately called functions before | |
| 3595 // seeing the call parentheses. | |
| 3596 parenthesized_function_ = (peek() == Token::FUNCTION); | |
| 3597 result = ParseExpression(true, CHECK_OK); | |
| 3598 Expect(Token::RPAREN, CHECK_OK); | |
| 3599 break; | |
| 3600 | |
| 3601 case Token::MOD: | |
| 3602 if (allow_natives_syntax() || extension_ != NULL) { | |
| 3603 result = ParseV8Intrinsic(CHECK_OK); | |
| 3604 break; | |
| 3605 } | |
| 3606 // If we're not allowing special syntax we fall-through to the | |
| 3607 // default case. | |
| 3608 | |
| 3609 default: { | |
| 3610 Token::Value tok = Next(); | |
| 3611 ReportUnexpectedToken(tok); | |
| 3612 *ok = false; | |
| 3613 return NULL; | |
| 3614 } | |
| 3615 } | |
| 3616 | |
| 3617 return result; | |
| 3618 } | |
| 3619 | |
| 3620 | |
| 3621 Expression* Parser::ParseArrayLiteral(bool* ok) { | |
| 3622 // ArrayLiteral :: | |
| 3623 // '[' Expression? (',' Expression?)* ']' | |
| 3624 | |
| 3625 int pos = peek_position(); | |
| 3626 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); | |
| 3627 Expect(Token::LBRACK, CHECK_OK); | |
| 3628 while (peek() != Token::RBRACK) { | |
| 3629 Expression* elem; | |
| 3630 if (peek() == Token::COMMA) { | |
| 3631 elem = GetLiteralTheHole(peek_position()); | |
| 3632 } else { | |
| 3633 elem = ParseAssignmentExpression(true, CHECK_OK); | |
| 3634 } | |
| 3635 values->Add(elem, zone()); | |
| 3636 if (peek() != Token::RBRACK) { | |
| 3637 Expect(Token::COMMA, CHECK_OK); | |
| 3638 } | |
| 3639 } | |
| 3640 Expect(Token::RBRACK, CHECK_OK); | |
| 3641 | |
| 3642 // Update the scope information before the pre-parsing bailout. | |
| 3643 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | |
| 3644 | |
| 3645 return factory()->NewArrayLiteral(values, literal_index, pos); | |
| 3646 } | |
| 3647 | |
| 3648 | |
| 3649 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3450 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3650 if (expression->AsLiteral() != NULL) return true; | 3451 if (expression->AsLiteral() != NULL) return true; |
| 3651 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3452 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3652 return lit != NULL && lit->is_simple(); | 3453 return lit != NULL && lit->is_simple(); |
| 3653 } | 3454 } |
| 3654 | 3455 |
| 3655 | 3456 |
| 3656 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, | 3457 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, |
| 3657 Expression* expression) { | 3458 Expression* expression) { |
| 3658 Factory* factory = isolate->factory(); | 3459 Factory* factory = isolate->factory(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3695 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3496 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3696 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3497 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3697 // )*[','] '}' | 3498 // )*[','] '}' |
| 3698 | 3499 |
| 3699 int pos = peek_position(); | 3500 int pos = peek_position(); |
| 3700 ZoneList<ObjectLiteral::Property*>* properties = | 3501 ZoneList<ObjectLiteral::Property*>* properties = |
| 3701 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 3502 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
| 3702 int number_of_boilerplate_properties = 0; | 3503 int number_of_boilerplate_properties = 0; |
| 3703 bool has_function = false; | 3504 bool has_function = false; |
| 3704 | 3505 |
| 3705 ObjectLiteralChecker checker(this, top_scope_->language_mode()); | 3506 ObjectLiteralChecker checker(this, scope_->language_mode()); |
| 3706 | 3507 |
| 3707 Expect(Token::LBRACE, CHECK_OK); | 3508 Expect(Token::LBRACE, CHECK_OK); |
| 3708 | 3509 |
| 3709 while (peek() != Token::RBRACE) { | 3510 while (peek() != Token::RBRACE) { |
| 3710 if (fni_ != NULL) fni_->Enter(); | 3511 if (fni_ != NULL) fni_->Enter(); |
| 3711 | 3512 |
| 3712 Literal* key = NULL; | 3513 Literal* key = NULL; |
| 3713 Token::Value next = peek(); | 3514 Token::Value next = peek(); |
| 3714 int next_pos = peek_position(); | 3515 int next_pos = peek_position(); |
| 3715 | 3516 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3741 return NULL; | 3542 return NULL; |
| 3742 } | 3543 } |
| 3743 // Validate the property. | 3544 // Validate the property. |
| 3744 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 3545 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 3745 checker.CheckProperty(next, type, CHECK_OK); | 3546 checker.CheckProperty(next, type, CHECK_OK); |
| 3746 Handle<String> name = is_keyword | 3547 Handle<String> name = is_keyword |
| 3747 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) | 3548 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) |
| 3748 : GetSymbol(); | 3549 : GetSymbol(); |
| 3749 FunctionLiteral* value = | 3550 FunctionLiteral* value = |
| 3750 ParseFunctionLiteral(name, | 3551 ParseFunctionLiteral(name, |
| 3552 scanner()->location(), |
| 3751 false, // reserved words are allowed here | 3553 false, // reserved words are allowed here |
| 3752 false, // not a generator | 3554 false, // not a generator |
| 3753 RelocInfo::kNoPosition, | 3555 RelocInfo::kNoPosition, |
| 3754 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3556 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3755 CHECK_OK); | 3557 CHECK_OK); |
| 3756 // Allow any number of parameters for compatibilty with JSC. | 3558 // Allow any number of parameters for compatibilty with JSC. |
| 3757 // Specification only allows zero parameters for get and one for set. | 3559 // Specification only allows zero parameters for get and one for set. |
| 3758 ObjectLiteral::Property* property = | 3560 ObjectLiteral::Property* property = |
| 3759 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | 3561 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 3760 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3562 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3781 uint32_t index; | 3583 uint32_t index; |
| 3782 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3584 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3783 key = factory()->NewNumberLiteral(index, next_pos); | 3585 key = factory()->NewNumberLiteral(index, next_pos); |
| 3784 break; | 3586 break; |
| 3785 } | 3587 } |
| 3786 key = factory()->NewLiteral(string, next_pos); | 3588 key = factory()->NewLiteral(string, next_pos); |
| 3787 break; | 3589 break; |
| 3788 } | 3590 } |
| 3789 case Token::NUMBER: { | 3591 case Token::NUMBER: { |
| 3790 Consume(Token::NUMBER); | 3592 Consume(Token::NUMBER); |
| 3791 ASSERT(scanner().is_literal_ascii()); | 3593 ASSERT(scanner()->is_literal_ascii()); |
| 3792 double value = StringToDouble(isolate()->unicode_cache(), | 3594 double value = StringToDouble(isolate()->unicode_cache(), |
| 3793 scanner().literal_ascii_string(), | 3595 scanner()->literal_ascii_string(), |
| 3794 ALLOW_HEX | ALLOW_OCTAL | | 3596 ALLOW_HEX | ALLOW_OCTAL | |
| 3795 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3597 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3796 key = factory()->NewNumberLiteral(value, next_pos); | 3598 key = factory()->NewNumberLiteral(value, next_pos); |
| 3797 break; | 3599 break; |
| 3798 } | 3600 } |
| 3799 default: | 3601 default: |
| 3800 if (Token::IsKeyword(next)) { | 3602 if (Token::IsKeyword(next)) { |
| 3801 Consume(next); | 3603 Consume(next); |
| 3802 Handle<String> string = GetSymbol(); | 3604 Handle<String> string = GetSymbol(); |
| 3803 key = factory()->NewLiteral(string, next_pos); | 3605 key = factory()->NewLiteral(string, next_pos); |
| 3804 } else { | 3606 } else { |
| 3805 // Unexpected token. | 3607 // Unexpected token. |
| 3806 Token::Value next = Next(); | 3608 Token::Value next = Next(); |
| 3807 ReportUnexpectedToken(next); | 3609 ReportUnexpectedToken(next); |
| 3808 *ok = false; | 3610 *ok = false; |
| 3809 return NULL; | 3611 return NULL; |
| 3810 } | 3612 } |
| 3811 } | 3613 } |
| 3812 | 3614 |
| 3813 // Validate the property | 3615 // Validate the property |
| 3814 checker.CheckProperty(next, kValueProperty, CHECK_OK); | 3616 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 3815 | 3617 |
| 3816 Expect(Token::COLON, CHECK_OK); | 3618 Expect(Token::COLON, CHECK_OK); |
| 3817 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3619 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 3818 | 3620 |
| 3819 ObjectLiteral::Property* property = | 3621 ObjectLiteral::Property* property = |
| 3820 new(zone()) ObjectLiteral::Property(key, value, isolate()); | 3622 factory()->NewObjectLiteralProperty(key, value); |
| 3821 | 3623 |
| 3822 // Mark top-level object literals that contain function literals and | 3624 // Mark top-level object literals that contain function literals and |
| 3823 // pretenure the literal so it can be added as a constant function | 3625 // pretenure the literal so it can be added as a constant function |
| 3824 // property. | 3626 // property. |
| 3825 if (top_scope_->DeclarationScope()->is_global_scope() && | 3627 if (scope_->DeclarationScope()->is_global_scope() && |
| 3826 value->AsFunctionLiteral() != NULL) { | 3628 value->AsFunctionLiteral() != NULL) { |
| 3827 has_function = true; | 3629 has_function = true; |
| 3828 value->AsFunctionLiteral()->set_pretenure(); | 3630 value->AsFunctionLiteral()->set_pretenure(); |
| 3829 } | 3631 } |
| 3830 | 3632 |
| 3831 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3633 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 3832 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3634 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
| 3833 number_of_boilerplate_properties++; | 3635 number_of_boilerplate_properties++; |
| 3834 } | 3636 } |
| 3835 properties->Add(property, zone()); | 3637 properties->Add(property, zone()); |
| 3836 | 3638 |
| 3837 // TODO(1240767): Consider allowing trailing comma. | 3639 // TODO(1240767): Consider allowing trailing comma. |
| 3838 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3640 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3839 | 3641 |
| 3840 if (fni_ != NULL) { | 3642 if (fni_ != NULL) { |
| 3841 fni_->Infer(); | 3643 fni_->Infer(); |
| 3842 fni_->Leave(); | 3644 fni_->Leave(); |
| 3843 } | 3645 } |
| 3844 } | 3646 } |
| 3845 Expect(Token::RBRACE, CHECK_OK); | 3647 Expect(Token::RBRACE, CHECK_OK); |
| 3846 | 3648 |
| 3847 // Computation of literal_index must happen before pre parse bailout. | 3649 // Computation of literal_index must happen before pre parse bailout. |
| 3848 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 3650 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 3849 | 3651 |
| 3850 return factory()->NewObjectLiteral(properties, | 3652 return factory()->NewObjectLiteral(properties, |
| 3851 literal_index, | 3653 literal_index, |
| 3852 number_of_boilerplate_properties, | 3654 number_of_boilerplate_properties, |
| 3853 has_function, | 3655 has_function, |
| 3854 pos); | 3656 pos); |
| 3855 } | 3657 } |
| 3856 | 3658 |
| 3857 | 3659 |
| 3858 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | |
| 3859 int pos = peek_position(); | |
| 3860 if (!scanner().ScanRegExpPattern(seen_equal)) { | |
| 3861 Next(); | |
| 3862 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | |
| 3863 *ok = false; | |
| 3864 return NULL; | |
| 3865 } | |
| 3866 | |
| 3867 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | |
| 3868 | |
| 3869 Handle<String> js_pattern = NextLiteralString(TENURED); | |
| 3870 scanner().ScanRegExpFlags(); | |
| 3871 Handle<String> js_flags = NextLiteralString(TENURED); | |
| 3872 Next(); | |
| 3873 | |
| 3874 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | |
| 3875 } | |
| 3876 | |
| 3877 | |
| 3878 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3660 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3879 // Arguments :: | 3661 // Arguments :: |
| 3880 // '(' (AssignmentExpression)*[','] ')' | 3662 // '(' (AssignmentExpression)*[','] ')' |
| 3881 | 3663 |
| 3882 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 3664 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3883 Expect(Token::LPAREN, CHECK_OK); | 3665 Expect(Token::LPAREN, CHECK_OK); |
| 3884 bool done = (peek() == Token::RPAREN); | 3666 bool done = (peek() == Token::RPAREN); |
| 3885 while (!done) { | 3667 while (!done) { |
| 3886 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | 3668 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); |
| 3887 result->Add(argument, zone()); | 3669 result->Add(argument, zone()); |
| 3888 if (result->length() > Code::kMaxArguments) { | 3670 if (result->length() > Code::kMaxArguments) { |
| 3889 ReportMessageAt(scanner().location(), "too_many_arguments", | 3671 ReportMessageAt(scanner()->location(), "too_many_arguments"); |
| 3890 Vector<const char*>::empty()); | |
| 3891 *ok = false; | 3672 *ok = false; |
| 3892 return NULL; | 3673 return NULL; |
| 3893 } | 3674 } |
| 3894 done = (peek() == Token::RPAREN); | 3675 done = (peek() == Token::RPAREN); |
| 3895 if (!done) Expect(Token::COMMA, CHECK_OK); | 3676 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3896 } | 3677 } |
| 3897 Expect(Token::RPAREN, CHECK_OK); | 3678 Expect(Token::RPAREN, CHECK_OK); |
| 3898 return result; | 3679 return result; |
| 3899 } | 3680 } |
| 3900 | 3681 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3987 int properties_; | 3768 int properties_; |
| 3988 LanguageMode mode_; | 3769 LanguageMode mode_; |
| 3989 // For error messages. | 3770 // For error messages. |
| 3990 const char* message_; | 3771 const char* message_; |
| 3991 const char* argument_opt_; | 3772 const char* argument_opt_; |
| 3992 }; | 3773 }; |
| 3993 | 3774 |
| 3994 | 3775 |
| 3995 FunctionLiteral* Parser::ParseFunctionLiteral( | 3776 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3996 Handle<String> function_name, | 3777 Handle<String> function_name, |
| 3778 Scanner::Location function_name_location, |
| 3997 bool name_is_strict_reserved, | 3779 bool name_is_strict_reserved, |
| 3998 bool is_generator, | 3780 bool is_generator, |
| 3999 int function_token_pos, | 3781 int function_token_pos, |
| 4000 FunctionLiteral::FunctionType function_type, | 3782 FunctionLiteral::FunctionType function_type, |
| 4001 bool* ok) { | 3783 bool* ok) { |
| 4002 // Function :: | 3784 // Function :: |
| 4003 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3785 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 4004 | 3786 |
| 4005 int pos = function_token_pos == RelocInfo::kNoPosition | 3787 int pos = function_token_pos == RelocInfo::kNoPosition |
| 4006 ? peek_position() : function_token_pos; | 3788 ? peek_position() : function_token_pos; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4036 // either information available directly, especially not when lazily compiling | 3818 // either information available directly, especially not when lazily compiling |
| 4037 // a function like 'g'. We hence rely on the following invariants: | 3819 // a function like 'g'. We hence rely on the following invariants: |
| 4038 // - (1) is the case iff the innermost scope of the deserialized scope chain | 3820 // - (1) is the case iff the innermost scope of the deserialized scope chain |
| 4039 // under which we compile is _not_ a declaration scope. This holds because | 3821 // under which we compile is _not_ a declaration scope. This holds because |
| 4040 // in all normal cases, function declarations are fully hoisted to a | 3822 // in all normal cases, function declarations are fully hoisted to a |
| 4041 // declaration scope and compiled relative to that. | 3823 // declaration scope and compiled relative to that. |
| 4042 // - (2) is the case iff the current declaration scope is still the original | 3824 // - (2) is the case iff the current declaration scope is still the original |
| 4043 // one relative to the deserialized scope chain. Otherwise we must be | 3825 // one relative to the deserialized scope chain. Otherwise we must be |
| 4044 // compiling a function in an inner declaration scope in the eval, e.g. a | 3826 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 4045 // nested function, and hoisting works normally relative to that. | 3827 // nested function, and hoisting works normally relative to that. |
| 4046 Scope* declaration_scope = top_scope_->DeclarationScope(); | 3828 Scope* declaration_scope = scope_->DeclarationScope(); |
| 4047 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 3829 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 4048 Scope* scope = | 3830 Scope* scope = |
| 4049 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && | 3831 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && |
| 4050 (original_scope_ == original_declaration_scope || | 3832 (original_scope_ == original_declaration_scope || |
| 4051 declaration_scope != original_declaration_scope) | 3833 declaration_scope != original_declaration_scope) |
| 4052 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 3834 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 4053 : NewScope(top_scope_, FUNCTION_SCOPE); | 3835 : NewScope(scope_, FUNCTION_SCOPE); |
| 4054 ZoneList<Statement*>* body = NULL; | 3836 ZoneList<Statement*>* body = NULL; |
| 4055 int materialized_literal_count = -1; | 3837 int materialized_literal_count = -1; |
| 4056 int expected_property_count = -1; | 3838 int expected_property_count = -1; |
| 4057 int handler_count = 0; | 3839 int handler_count = 0; |
| 4058 FunctionLiteral::ParameterFlag duplicate_parameters = | 3840 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 4059 FunctionLiteral::kNoDuplicateParameters; | 3841 FunctionLiteral::kNoDuplicateParameters; |
| 4060 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3842 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 4061 ? FunctionLiteral::kIsParenthesized | 3843 ? FunctionLiteral::kIsParenthesized |
| 4062 : FunctionLiteral::kNotParenthesized; | 3844 : FunctionLiteral::kNotParenthesized; |
| 4063 FunctionLiteral::IsGeneratorFlag generator = is_generator | 3845 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 4064 ? FunctionLiteral::kIsGenerator | 3846 ? FunctionLiteral::kIsGenerator |
| 4065 : FunctionLiteral::kNotGenerator; | 3847 : FunctionLiteral::kNotGenerator; |
| 3848 DeferredFeedbackSlotProcessor* slot_processor; |
| 4066 AstProperties ast_properties; | 3849 AstProperties ast_properties; |
| 4067 BailoutReason dont_optimize_reason = kNoReason; | 3850 BailoutReason dont_optimize_reason = kNoReason; |
| 4068 // Parse function body. | 3851 // Parse function body. |
| 4069 { FunctionState function_state(this, scope, isolate()); | 3852 { FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 4070 top_scope_->SetScopeName(function_name); | 3853 scope_->SetScopeName(function_name); |
| 4071 | 3854 |
| 4072 if (is_generator) { | 3855 if (is_generator) { |
| 4073 // For generators, allocating variables in contexts is currently a win | 3856 // For generators, allocating variables in contexts is currently a win |
| 4074 // because it minimizes the work needed to suspend and resume an | 3857 // because it minimizes the work needed to suspend and resume an |
| 4075 // activation. | 3858 // activation. |
| 4076 top_scope_->ForceContextAllocation(); | 3859 scope_->ForceContextAllocation(); |
| 4077 | 3860 |
| 4078 // Calling a generator returns a generator object. That object is stored | 3861 // Calling a generator returns a generator object. That object is stored |
| 4079 // in a temporary variable, a definition that is used by "yield" | 3862 // in a temporary variable, a definition that is used by "yield" |
| 4080 // expressions. Presence of a variable for the generator object in the | 3863 // expressions. This also marks the FunctionState as a generator. |
| 4081 // FunctionState indicates that this function is a generator. | 3864 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 4082 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( | |
| 4083 isolate()->factory()->dot_generator_object_string()); | 3865 isolate()->factory()->dot_generator_object_string()); |
| 4084 function_state.set_generator_object_variable(temp); | 3866 function_state.set_generator_object_variable(temp); |
| 4085 } | 3867 } |
| 4086 | 3868 |
| 4087 // FormalParameterList :: | 3869 // FormalParameterList :: |
| 4088 // '(' (Identifier)*[','] ')' | 3870 // '(' (Identifier)*[','] ')' |
| 4089 Expect(Token::LPAREN, CHECK_OK); | 3871 Expect(Token::LPAREN, CHECK_OK); |
| 4090 scope->set_start_position(scanner().location().beg_pos); | 3872 scope->set_start_position(scanner()->location().beg_pos); |
| 4091 ScannerBase::Location name_loc = ScannerBase::Location::invalid(); | 3873 |
| 4092 ScannerBase::Location dupe_loc = ScannerBase::Location::invalid(); | 3874 // We don't yet know if the function will be strict, so we cannot yet |
| 4093 ScannerBase::Location reserved_loc = ScannerBase::Location::invalid(); | 3875 // produce errors for parameter names or duplicates. However, we remember |
| 3876 // the locations of these errors if they occur and produce the errors later. |
| 3877 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 3878 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 3879 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 4094 | 3880 |
| 4095 bool done = (peek() == Token::RPAREN); | 3881 bool done = (peek() == Token::RPAREN); |
| 4096 while (!done) { | 3882 while (!done) { |
| 4097 bool is_strict_reserved = false; | 3883 bool is_strict_reserved = false; |
| 4098 Handle<String> param_name = | 3884 Handle<String> param_name = |
| 4099 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3885 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 4100 | 3886 |
| 4101 // Store locations for possible future error reports. | 3887 // Store locations for possible future error reports. |
| 4102 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { | 3888 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 4103 name_loc = scanner().location(); | 3889 eval_args_error_log = scanner()->location(); |
| 4104 } | |
| 4105 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | |
| 4106 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | |
| 4107 dupe_loc = scanner().location(); | |
| 4108 } | 3890 } |
| 4109 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3891 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 4110 reserved_loc = scanner().location(); | 3892 reserved_loc = scanner()->location(); |
| 3893 } |
| 3894 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 3895 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3896 dupe_error_loc = scanner()->location(); |
| 4111 } | 3897 } |
| 4112 | 3898 |
| 4113 top_scope_->DeclareParameter(param_name, VAR); | 3899 scope_->DeclareParameter(param_name, VAR); |
| 4114 num_parameters++; | 3900 num_parameters++; |
| 4115 if (num_parameters > Code::kMaxArguments) { | 3901 if (num_parameters > Code::kMaxArguments) { |
| 4116 ReportMessageAt(scanner().location(), "too_many_parameters", | 3902 ReportMessageAt(scanner()->location(), "too_many_parameters"); |
| 4117 Vector<const char*>::empty()); | |
| 4118 *ok = false; | 3903 *ok = false; |
| 4119 return NULL; | 3904 return NULL; |
| 4120 } | 3905 } |
| 4121 done = (peek() == Token::RPAREN); | 3906 done = (peek() == Token::RPAREN); |
| 4122 if (!done) Expect(Token::COMMA, CHECK_OK); | 3907 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 4123 } | 3908 } |
| 4124 Expect(Token::RPAREN, CHECK_OK); | 3909 Expect(Token::RPAREN, CHECK_OK); |
| 4125 | 3910 |
| 4126 Expect(Token::LBRACE, CHECK_OK); | 3911 Expect(Token::LBRACE, CHECK_OK); |
| 4127 | 3912 |
| 4128 // If we have a named function expression, we add a local variable | 3913 // If we have a named function expression, we add a local variable |
| 4129 // declaration to the body of the function with the name of the | 3914 // declaration to the body of the function with the name of the |
| 4130 // function and let it refer to the function itself (closure). | 3915 // function and let it refer to the function itself (closure). |
| 4131 // NOTE: We create a proxy and resolve it here so that in the | 3916 // NOTE: We create a proxy and resolve it here so that in the |
| 4132 // future we can change the AST to only refer to VariableProxies | 3917 // future we can change the AST to only refer to VariableProxies |
| 4133 // instead of Variables and Proxis as is the case now. | 3918 // instead of Variables and Proxis as is the case now. |
| 4134 Variable* fvar = NULL; | 3919 Variable* fvar = NULL; |
| 4135 Token::Value fvar_init_op = Token::INIT_CONST; | 3920 Token::Value fvar_init_op = Token::INIT_CONST; |
| 4136 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3921 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 4137 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 3922 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
| 4138 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 3923 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
| 4139 fvar = new(zone()) Variable(top_scope_, | 3924 fvar = new(zone()) Variable(scope_, |
| 4140 function_name, fvar_mode, true /* is valid LHS */, | 3925 function_name, fvar_mode, true /* is valid LHS */, |
| 4141 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3926 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 4142 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3927 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 4143 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3928 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 4144 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); | 3929 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 4145 top_scope_->DeclareFunctionVar(fvar_declaration); | 3930 scope_->DeclareFunctionVar(fvar_declaration); |
| 4146 } | 3931 } |
| 4147 | 3932 |
| 4148 // Determine whether the function will be lazily compiled. | 3933 // Determine if the function can be parsed lazily. Lazy parsing is different |
| 4149 // The heuristics are: | 3934 // from lazy compilation; we need to parse more eagerly than we compile. |
| 3935 |
| 3936 // We can only parse lazily if we also compile lazily. The heuristics for |
| 3937 // lazy compilation are: |
| 4150 // - It must not have been prohibited by the caller to Parse (some callers | 3938 // - It must not have been prohibited by the caller to Parse (some callers |
| 4151 // need a full AST). | 3939 // need a full AST). |
| 4152 // - The outer scope must allow lazy compilation of inner functions. | 3940 // - The outer scope must allow lazy compilation of inner functions. |
| 4153 // - The function mustn't be a function expression with an open parenthesis | 3941 // - The function mustn't be a function expression with an open parenthesis |
| 4154 // before; we consider that a hint that the function will be called | 3942 // before; we consider that a hint that the function will be called |
| 4155 // immediately, and it would be a waste of time to make it lazily | 3943 // immediately, and it would be a waste of time to make it lazily |
| 4156 // compiled. | 3944 // compiled. |
| 4157 // These are all things we can know at this point, without looking at the | 3945 // These are all things we can know at this point, without looking at the |
| 4158 // function itself. | 3946 // function itself. |
| 4159 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 3947 |
| 4160 top_scope_->AllowsLazyCompilation() && | 3948 // In addition, we need to distinguish between these cases: |
| 4161 !parenthesized_function_); | 3949 // (function foo() { |
| 3950 // bar = function() { return 1; } |
| 3951 // })(); |
| 3952 // and |
| 3953 // (function foo() { |
| 3954 // var a = 1; |
| 3955 // bar = function() { return a; } |
| 3956 // })(); |
| 3957 |
| 3958 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume |
| 3959 // parenthesis before the function means that it will be called |
| 3960 // immediately). The inner function *must* be parsed eagerly to resolve the |
| 3961 // possible reference to the variable in foo's scope. However, it's possible |
| 3962 // that it will be compiled lazily. |
| 3963 |
| 3964 // To make this additional case work, both Parser and PreParser implement a |
| 3965 // logic where only top-level functions will be parsed lazily. |
| 3966 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| 3967 scope_->AllowsLazyCompilation() && |
| 3968 !parenthesized_function_); |
| 4162 parenthesized_function_ = false; // The bit was set for this function only. | 3969 parenthesized_function_ = false; // The bit was set for this function only. |
| 4163 | 3970 |
| 4164 if (is_lazily_compiled) { | 3971 if (is_lazily_parsed) { |
| 4165 int function_block_pos = position(); | 3972 int function_block_pos = position(); |
| 4166 FunctionEntry entry; | 3973 FunctionEntry entry; |
| 4167 if (pre_parse_data_ != NULL) { | 3974 if (pre_parse_data_ != NULL) { |
| 4168 // If we have pre_parse_data_, we use it to skip parsing the function | 3975 // If we have pre_parse_data_, we use it to skip parsing the function |
| 4169 // body. The preparser data contains the information we need to | 3976 // body. The preparser data contains the information we need to |
| 4170 // construct the lazy function. | 3977 // construct the lazy function. |
| 4171 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 3978 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
| 4172 if (entry.is_valid()) { | 3979 if (entry.is_valid()) { |
| 4173 if (entry.end_pos() <= function_block_pos) { | 3980 if (entry.end_pos() <= function_block_pos) { |
| 4174 // End position greater than end of stream is safe, and hard | 3981 // End position greater than end of stream is safe, and hard |
| 4175 // to check. | 3982 // to check. |
| 4176 ReportInvalidPreparseData(function_name, CHECK_OK); | 3983 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 4177 } | 3984 } |
| 4178 scanner().SeekForward(entry.end_pos() - 1); | 3985 scanner()->SeekForward(entry.end_pos() - 1); |
| 4179 | 3986 |
| 4180 scope->set_end_position(entry.end_pos()); | 3987 scope->set_end_position(entry.end_pos()); |
| 4181 Expect(Token::RBRACE, CHECK_OK); | 3988 Expect(Token::RBRACE, CHECK_OK); |
| 4182 isolate()->counters()->total_preparse_skipped()->Increment( | 3989 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4183 scope->end_position() - function_block_pos); | 3990 scope->end_position() - function_block_pos); |
| 4184 materialized_literal_count = entry.literal_count(); | 3991 materialized_literal_count = entry.literal_count(); |
| 4185 expected_property_count = entry.property_count(); | 3992 expected_property_count = entry.property_count(); |
| 4186 top_scope_->SetLanguageMode(entry.language_mode()); | 3993 scope_->SetLanguageMode(entry.language_mode()); |
| 4187 } else { | 3994 } else { |
| 4188 is_lazily_compiled = false; | 3995 // This case happens when we have preparse data but it doesn't contain |
| 3996 // an entry for the function. As a safety net, fall back to eager |
| 3997 // parsing. It is unclear whether PreParser's laziness analysis can |
| 3998 // produce different results than the Parser's laziness analysis (see |
| 3999 // https://codereview.chromium.org/7565003 ). This safety net is |
| 4000 // guarding against the case where Parser thinks a function should be |
| 4001 // lazily parsed, but PreParser thinks it should be eagerly parsed -- |
| 4002 // in that case we fall back to eager parsing in Parser, too. Note |
| 4003 // that the opposite case is worse: if PreParser thinks a function |
| 4004 // should be lazily parsed, but Parser thinks it should be eagerly |
| 4005 // parsed, it will never advance the preparse data beyond that |
| 4006 // function and all further laziness will fail (all functions will be |
| 4007 // parsed eagerly). |
| 4008 is_lazily_parsed = false; |
| 4189 } | 4009 } |
| 4190 } else { | 4010 } else { |
| 4191 // With no preparser data, we partially parse the function, without | 4011 // With no preparser data, we partially parse the function, without |
| 4192 // building an AST. This gathers the data needed to build a lazy | 4012 // building an AST. This gathers the data needed to build a lazy |
| 4193 // function. | 4013 // function. |
| 4194 SingletonLogger logger; | 4014 SingletonLogger logger; |
| 4195 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); | 4015 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
| 4196 if (result == PreParser::kPreParseStackOverflow) { | 4016 if (result == PreParser::kPreParseStackOverflow) { |
| 4197 // Propagate stack overflow. | 4017 // Propagate stack overflow. |
| 4198 set_stack_overflow(); | 4018 set_stack_overflow(); |
| 4199 *ok = false; | 4019 *ok = false; |
| 4200 return NULL; | 4020 return NULL; |
| 4201 } | 4021 } |
| 4202 if (logger.has_error()) { | 4022 if (logger.has_error()) { |
| 4203 const char* arg = logger.argument_opt(); | 4023 const char* arg = logger.argument_opt(); |
| 4204 Vector<const char*> args; | 4024 Vector<const char*> args; |
| 4205 if (arg != NULL) { | 4025 if (arg != NULL) { |
| 4206 args = Vector<const char*>(&arg, 1); | 4026 args = Vector<const char*>(&arg, 1); |
| 4207 } | 4027 } |
| 4208 ReportMessageAt(ScannerBase::Location(logger.start(), logger.end()), | 4028 ParserTraits::ReportMessageAt( |
| 4209 logger.message(), args); | 4029 Scanner::Location(logger.start(), logger.end()), |
| 4030 logger.message(), |
| 4031 args); |
| 4210 *ok = false; | 4032 *ok = false; |
| 4211 return NULL; | 4033 return NULL; |
| 4212 } | 4034 } |
| 4213 scope->set_end_position(logger.end()); | 4035 scope->set_end_position(logger.end()); |
| 4214 Expect(Token::RBRACE, CHECK_OK); | 4036 Expect(Token::RBRACE, CHECK_OK); |
| 4215 isolate()->counters()->total_preparse_skipped()->Increment( | 4037 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4216 scope->end_position() - function_block_pos); | 4038 scope->end_position() - function_block_pos); |
| 4217 materialized_literal_count = logger.literals(); | 4039 materialized_literal_count = logger.literals(); |
| 4218 expected_property_count = logger.properties(); | 4040 expected_property_count = logger.properties(); |
| 4219 top_scope_->SetLanguageMode(logger.language_mode()); | 4041 scope_->SetLanguageMode(logger.language_mode()); |
| 4220 } | 4042 } |
| 4221 } | 4043 } |
| 4222 | 4044 |
| 4223 if (!is_lazily_compiled) { | 4045 if (!is_lazily_parsed) { |
| 4046 // Everything inside an eagerly parsed function will be parsed eagerly |
| 4047 // (see comment above). |
| 4224 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4048 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 4225 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4049 body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 4226 if (fvar != NULL) { | 4050 if (fvar != NULL) { |
| 4227 VariableProxy* fproxy = top_scope_->NewUnresolved( | 4051 VariableProxy* fproxy = scope_->NewUnresolved( |
| 4228 factory(), function_name, Interface::NewConst()); | 4052 factory(), function_name, Interface::NewConst()); |
| 4229 fproxy->BindTo(fvar); | 4053 fproxy->BindTo(fvar); |
| 4230 body->Add(factory()->NewExpressionStatement( | 4054 body->Add(factory()->NewExpressionStatement( |
| 4231 factory()->NewAssignment(fvar_init_op, | 4055 factory()->NewAssignment(fvar_init_op, |
| 4232 fproxy, | 4056 fproxy, |
| 4233 factory()->NewThisFunction(pos), | 4057 factory()->NewThisFunction(pos), |
| 4234 RelocInfo::kNoPosition), | 4058 RelocInfo::kNoPosition), |
| 4235 RelocInfo::kNoPosition), zone()); | 4059 RelocInfo::kNoPosition), zone()); |
| 4236 } | 4060 } |
| 4237 | 4061 |
| 4238 // For generators, allocate and yield an iterator on function entry. | 4062 // For generators, allocate and yield an iterator on function entry. |
| 4239 if (is_generator) { | 4063 if (is_generator) { |
| 4240 ZoneList<Expression*>* arguments = | 4064 ZoneList<Expression*>* arguments = |
| 4241 new(zone()) ZoneList<Expression*>(0, zone()); | 4065 new(zone()) ZoneList<Expression*>(0, zone()); |
| 4242 CallRuntime* allocation = factory()->NewCallRuntime( | 4066 CallRuntime* allocation = factory()->NewCallRuntime( |
| 4243 isolate()->factory()->empty_string(), | 4067 isolate()->factory()->empty_string(), |
| 4244 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4068 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
| 4245 arguments, pos); | 4069 arguments, pos); |
| 4246 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4070 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 4247 current_function_state_->generator_object_variable()); | 4071 function_state_->generator_object_variable()); |
| 4248 Assignment* assignment = factory()->NewAssignment( | 4072 Assignment* assignment = factory()->NewAssignment( |
| 4249 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4073 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 4250 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4074 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4251 current_function_state_->generator_object_variable()); | 4075 function_state_->generator_object_variable()); |
| 4252 Yield* yield = factory()->NewYield( | 4076 Yield* yield = factory()->NewYield( |
| 4253 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4077 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 4254 body->Add(factory()->NewExpressionStatement( | 4078 body->Add(factory()->NewExpressionStatement( |
| 4255 yield, RelocInfo::kNoPosition), zone()); | 4079 yield, RelocInfo::kNoPosition), zone()); |
| 4256 } | 4080 } |
| 4257 | 4081 |
| 4258 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4082 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 4259 | 4083 |
| 4260 if (is_generator) { | 4084 if (is_generator) { |
| 4261 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4085 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4262 current_function_state_->generator_object_variable()); | 4086 function_state_->generator_object_variable()); |
| 4263 Expression *undefined = factory()->NewLiteral( | 4087 Expression *undefined = factory()->NewLiteral( |
| 4264 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 4088 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| 4265 Yield* yield = factory()->NewYield( | 4089 Yield* yield = factory()->NewYield( |
| 4266 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4090 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| 4267 body->Add(factory()->NewExpressionStatement( | 4091 body->Add(factory()->NewExpressionStatement( |
| 4268 yield, RelocInfo::kNoPosition), zone()); | 4092 yield, RelocInfo::kNoPosition), zone()); |
| 4269 } | 4093 } |
| 4270 | 4094 |
| 4271 materialized_literal_count = function_state.materialized_literal_count(); | 4095 materialized_literal_count = function_state.materialized_literal_count(); |
| 4272 expected_property_count = function_state.expected_property_count(); | 4096 expected_property_count = function_state.expected_property_count(); |
| 4273 handler_count = function_state.handler_count(); | 4097 handler_count = function_state.handler_count(); |
| 4274 | 4098 |
| 4275 Expect(Token::RBRACE, CHECK_OK); | 4099 Expect(Token::RBRACE, CHECK_OK); |
| 4276 scope->set_end_position(scanner().location().end_pos); | 4100 scope->set_end_position(scanner()->location().end_pos); |
| 4277 } | 4101 } |
| 4278 | 4102 |
| 4279 // Validate strict mode. | 4103 // Validate strict mode. We can do this only after parsing the function, |
| 4280 if (!top_scope_->is_classic_mode()) { | 4104 // since the function can declare itself strict. |
| 4105 if (!scope_->is_classic_mode()) { |
| 4281 if (IsEvalOrArguments(function_name)) { | 4106 if (IsEvalOrArguments(function_name)) { |
| 4282 int start_pos = scope->start_position(); | 4107 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
| 4283 int position = function_token_pos != RelocInfo::kNoPosition | |
| 4284 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4285 ScannerBase::Location location = | |
| 4286 ScannerBase::Location(position, start_pos); | |
| 4287 ReportMessageAt(location, | |
| 4288 "strict_function_name", Vector<const char*>::empty()); | |
| 4289 *ok = false; | |
| 4290 return NULL; | |
| 4291 } | |
| 4292 if (name_loc.IsValid()) { | |
| 4293 ReportMessageAt(name_loc, "strict_param_name", | |
| 4294 Vector<const char*>::empty()); | |
| 4295 *ok = false; | |
| 4296 return NULL; | |
| 4297 } | |
| 4298 if (dupe_loc.IsValid()) { | |
| 4299 ReportMessageAt(dupe_loc, "strict_param_dupe", | |
| 4300 Vector<const char*>::empty()); | |
| 4301 *ok = false; | 4108 *ok = false; |
| 4302 return NULL; | 4109 return NULL; |
| 4303 } | 4110 } |
| 4304 if (name_is_strict_reserved) { | 4111 if (name_is_strict_reserved) { |
| 4305 int start_pos = scope->start_position(); | 4112 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
| 4306 int position = function_token_pos != RelocInfo::kNoPosition | 4113 *ok = false; |
| 4307 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | 4114 return NULL; |
| 4308 ScannerBase::Location location = | 4115 } |
| 4309 ScannerBase::Location(position, start_pos); | 4116 if (eval_args_error_log.IsValid()) { |
| 4310 ReportMessageAt(location, "strict_reserved_word", | 4117 ReportMessageAt(eval_args_error_log, "strict_eval_arguments"); |
| 4311 Vector<const char*>::empty()); | 4118 *ok = false; |
| 4119 return NULL; |
| 4120 } |
| 4121 if (dupe_error_loc.IsValid()) { |
| 4122 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); |
| 4312 *ok = false; | 4123 *ok = false; |
| 4313 return NULL; | 4124 return NULL; |
| 4314 } | 4125 } |
| 4315 if (reserved_loc.IsValid()) { | 4126 if (reserved_loc.IsValid()) { |
| 4316 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4127 ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 4317 Vector<const char*>::empty()); | |
| 4318 *ok = false; | 4128 *ok = false; |
| 4319 return NULL; | 4129 return NULL; |
| 4320 } | 4130 } |
| 4321 CheckOctalLiteral(scope->start_position(), | 4131 CheckOctalLiteral(scope->start_position(), |
| 4322 scope->end_position(), | 4132 scope->end_position(), |
| 4323 CHECK_OK); | 4133 CHECK_OK); |
| 4324 } | 4134 } |
| 4325 ast_properties = *factory()->visitor()->ast_properties(); | 4135 ast_properties = *factory()->visitor()->ast_properties(); |
| 4136 slot_processor = factory()->visitor()->slot_processor(); |
| 4326 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 4137 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| 4327 } | 4138 } |
| 4328 | 4139 |
| 4329 if (is_extended_mode()) { | 4140 if (is_extended_mode()) { |
| 4330 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4141 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4331 } | 4142 } |
| 4332 | 4143 |
| 4333 FunctionLiteral* function_literal = | 4144 FunctionLiteral* function_literal = |
| 4334 factory()->NewFunctionLiteral(function_name, | 4145 factory()->NewFunctionLiteral(function_name, |
| 4335 scope, | 4146 scope, |
| 4336 body, | 4147 body, |
| 4337 materialized_literal_count, | 4148 materialized_literal_count, |
| 4338 expected_property_count, | 4149 expected_property_count, |
| 4339 handler_count, | 4150 handler_count, |
| 4340 num_parameters, | 4151 num_parameters, |
| 4341 duplicate_parameters, | 4152 duplicate_parameters, |
| 4342 function_type, | 4153 function_type, |
| 4343 FunctionLiteral::kIsFunction, | 4154 FunctionLiteral::kIsFunction, |
| 4344 parenthesized, | 4155 parenthesized, |
| 4345 generator, | 4156 generator, |
| 4346 pos); | 4157 pos); |
| 4347 function_literal->set_function_token_position(function_token_pos); | 4158 function_literal->set_function_token_position(function_token_pos); |
| 4348 function_literal->set_ast_properties(&ast_properties); | 4159 function_literal->set_ast_properties(&ast_properties); |
| 4160 function_literal->set_slot_processor(slot_processor); |
| 4349 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4161 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 4350 | 4162 |
| 4351 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4163 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4352 return function_literal; | 4164 return function_literal; |
| 4353 } | 4165 } |
| 4354 | 4166 |
| 4355 | 4167 |
| 4356 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4168 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4357 SingletonLogger* logger) { | 4169 SingletonLogger* logger) { |
| 4358 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4170 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4359 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4171 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); |
| 4360 | 4172 |
| 4361 if (reusable_preparser_ == NULL) { | 4173 if (reusable_preparser_ == NULL) { |
| 4362 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4174 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4363 reusable_preparser_ = new PreParser(scanner_, NULL, stack_limit); | 4175 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
| 4364 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4176 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4365 reusable_preparser_->set_allow_modules(allow_modules()); | 4177 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4366 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4178 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4367 reusable_preparser_->set_allow_lazy(true); | 4179 reusable_preparser_->set_allow_lazy(true); |
| 4368 reusable_preparser_->set_allow_generators(allow_generators()); | 4180 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4369 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4181 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4370 reusable_preparser_->set_allow_harmony_numeric_literals( | 4182 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4371 allow_harmony_numeric_literals()); | 4183 allow_harmony_numeric_literals()); |
| 4372 } | 4184 } |
| 4373 PreParser::PreParseResult result = | 4185 PreParser::PreParseResult result = |
| 4374 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4186 reusable_preparser_->PreParseLazyFunction(scope_->language_mode(), |
| 4375 is_generator(), | 4187 is_generator(), |
| 4376 logger); | 4188 logger); |
| 4377 return result; | 4189 return result; |
| 4378 } | 4190 } |
| 4379 | 4191 |
| 4380 | 4192 |
| 4381 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4193 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4382 // CallRuntime :: | 4194 // CallRuntime :: |
| 4383 // '%' Identifier Arguments | 4195 // '%' Identifier Arguments |
| 4384 | 4196 |
| 4385 int pos = peek_position(); | 4197 int pos = peek_position(); |
| 4386 Expect(Token::MOD, CHECK_OK); | 4198 Expect(Token::MOD, CHECK_OK); |
| 4387 Handle<String> name = ParseIdentifier(CHECK_OK); | 4199 // Allow "eval" or "arguments" for backward compatibility. |
| 4200 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 4388 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4201 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4389 | 4202 |
| 4390 if (extension_ != NULL) { | 4203 if (extension_ != NULL) { |
| 4391 // The extension structures are only accessible while parsing the | 4204 // The extension structures are only accessible while parsing the |
| 4392 // very first time not when reparsing because of lazy compilation. | 4205 // very first time not when reparsing because of lazy compilation. |
| 4393 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4206 scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4394 } | 4207 } |
| 4395 | 4208 |
| 4396 const Runtime::Function* function = Runtime::FunctionForName(name); | 4209 const Runtime::Function* function = Runtime::FunctionForName(name); |
| 4397 | 4210 |
| 4398 // Check for built-in IS_VAR macro. | 4211 // Check for built-in IS_VAR macro. |
| 4399 if (function != NULL && | 4212 if (function != NULL && |
| 4400 function->intrinsic_type == Runtime::RUNTIME && | 4213 function->intrinsic_type == Runtime::RUNTIME && |
| 4401 function->function_id == Runtime::kIS_VAR) { | 4214 function->function_id == Runtime::kIS_VAR) { |
| 4402 // %IS_VAR(x) evaluates to x if x is a variable, | 4215 // %IS_VAR(x) evaluates to x if x is a variable, |
| 4403 // leads to a parse error otherwise. Could be implemented as an | 4216 // leads to a parse error otherwise. Could be implemented as an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4415 if (function != NULL && | 4228 if (function != NULL && |
| 4416 function->nargs != -1 && | 4229 function->nargs != -1 && |
| 4417 function->nargs != args->length()) { | 4230 function->nargs != args->length()) { |
| 4418 ReportMessage("illegal_access", Vector<const char*>::empty()); | 4231 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 4419 *ok = false; | 4232 *ok = false; |
| 4420 return NULL; | 4233 return NULL; |
| 4421 } | 4234 } |
| 4422 | 4235 |
| 4423 // Check that the function is defined if it's an inline runtime call. | 4236 // Check that the function is defined if it's an inline runtime call. |
| 4424 if (function == NULL && name->Get(0) == '_') { | 4237 if (function == NULL && name->Get(0) == '_') { |
| 4425 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4238 ParserTraits::ReportMessage("not_defined", |
| 4239 Vector<Handle<String> >(&name, 1)); |
| 4426 *ok = false; | 4240 *ok = false; |
| 4427 return NULL; | 4241 return NULL; |
| 4428 } | 4242 } |
| 4429 | 4243 |
| 4430 // We have a valid intrinsics call or a call to a builtin. | 4244 // We have a valid intrinsics call or a call to a builtin. |
| 4431 return factory()->NewCallRuntime(name, function, args, pos); | 4245 return factory()->NewCallRuntime(name, function, args, pos); |
| 4432 } | 4246 } |
| 4433 | 4247 |
| 4434 | 4248 |
| 4435 bool ParserBase::peek_any_identifier() { | |
| 4436 Token::Value next = peek(); | |
| 4437 return next == Token::IDENTIFIER || | |
| 4438 next == Token::FUTURE_RESERVED_WORD || | |
| 4439 next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4440 next == Token::YIELD; | |
| 4441 } | |
| 4442 | |
| 4443 | |
| 4444 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { | |
| 4445 if (peek() == Token::IDENTIFIER && | |
| 4446 scanner()->is_next_contextual_keyword(keyword)) { | |
| 4447 Consume(Token::IDENTIFIER); | |
| 4448 return true; | |
| 4449 } | |
| 4450 return false; | |
| 4451 } | |
| 4452 | |
| 4453 | |
| 4454 void ParserBase::ExpectSemicolon(bool* ok) { | |
| 4455 // Check for automatic semicolon insertion according to | |
| 4456 // the rules given in ECMA-262, section 7.9, page 21. | |
| 4457 Token::Value tok = peek(); | |
| 4458 if (tok == Token::SEMICOLON) { | |
| 4459 Next(); | |
| 4460 return; | |
| 4461 } | |
| 4462 if (scanner()->HasAnyLineTerminatorBeforeNext() || | |
| 4463 tok == Token::RBRACE || | |
| 4464 tok == Token::EOS) { | |
| 4465 return; | |
| 4466 } | |
| 4467 Expect(Token::SEMICOLON, ok); | |
| 4468 } | |
| 4469 | |
| 4470 | |
| 4471 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | |
| 4472 Expect(Token::IDENTIFIER, ok); | |
| 4473 if (!*ok) return; | |
| 4474 if (!scanner()->is_literal_contextual_keyword(keyword)) { | |
| 4475 ReportUnexpectedToken(scanner()->current_token()); | |
| 4476 *ok = false; | |
| 4477 } | |
| 4478 } | |
| 4479 | |
| 4480 | |
| 4481 Literal* Parser::GetLiteralUndefined(int position) { | 4249 Literal* Parser::GetLiteralUndefined(int position) { |
| 4482 return factory()->NewLiteral( | 4250 return factory()->NewLiteral( |
| 4483 isolate()->factory()->undefined_value(), position); | 4251 isolate()->factory()->undefined_value(), position); |
| 4484 } | 4252 } |
| 4485 | 4253 |
| 4486 | 4254 |
| 4487 Literal* Parser::GetLiteralTheHole(int position) { | |
| 4488 return factory()->NewLiteral( | |
| 4489 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | |
| 4490 } | |
| 4491 | |
| 4492 | |
| 4493 // Parses an identifier that is valid for the current scope, in particular it | |
| 4494 // fails on strict mode future reserved keywords in a strict scope. | |
| 4495 Handle<String> Parser::ParseIdentifier(bool* ok) { | |
| 4496 Token::Value next = Next(); | |
| 4497 if (next == Token::IDENTIFIER || | |
| 4498 (top_scope_->is_classic_mode() && | |
| 4499 (next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4500 (next == Token::YIELD && !is_generator())))) { | |
| 4501 return GetSymbol(); | |
| 4502 } else { | |
| 4503 ReportUnexpectedToken(next); | |
| 4504 *ok = false; | |
| 4505 return Handle<String>(); | |
| 4506 } | |
| 4507 } | |
| 4508 | |
| 4509 | |
| 4510 // Parses and identifier or a strict mode future reserved word, and indicate | |
| 4511 // whether it is strict mode future reserved. | |
| 4512 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( | |
| 4513 bool* is_strict_reserved, bool* ok) { | |
| 4514 Token::Value next = Next(); | |
| 4515 if (next == Token::IDENTIFIER) { | |
| 4516 *is_strict_reserved = false; | |
| 4517 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4518 (next == Token::YIELD && !is_generator())) { | |
| 4519 *is_strict_reserved = true; | |
| 4520 } else { | |
| 4521 ReportUnexpectedToken(next); | |
| 4522 *ok = false; | |
| 4523 return Handle<String>(); | |
| 4524 } | |
| 4525 return GetSymbol(); | |
| 4526 } | |
| 4527 | |
| 4528 | |
| 4529 Handle<String> Parser::ParseIdentifierName(bool* ok) { | |
| 4530 Token::Value next = Next(); | |
| 4531 if (next != Token::IDENTIFIER && | |
| 4532 next != Token::FUTURE_RESERVED_WORD && | |
| 4533 next != Token::FUTURE_STRICT_RESERVED_WORD && | |
| 4534 !Token::IsKeyword(next)) { | |
| 4535 ReportUnexpectedToken(next); | |
| 4536 *ok = false; | |
| 4537 return Handle<String>(); | |
| 4538 } | |
| 4539 return GetSymbol(); | |
| 4540 } | |
| 4541 | |
| 4542 | |
| 4543 void Parser::MarkAsLValue(Expression* expression) { | 4255 void Parser::MarkAsLValue(Expression* expression) { |
| 4544 VariableProxy* proxy = expression != NULL | 4256 VariableProxy* proxy = expression != NULL |
| 4545 ? expression->AsVariableProxy() | 4257 ? expression->AsVariableProxy() |
| 4546 : NULL; | 4258 : NULL; |
| 4547 | 4259 |
| 4548 if (proxy != NULL) proxy->MarkAsLValue(); | 4260 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4549 } | 4261 } |
| 4550 | 4262 |
| 4551 | 4263 |
| 4552 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4264 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 4553 // in strict mode. | 4265 // in strict mode. |
| 4554 void Parser::CheckStrictModeLValue(Expression* expression, | 4266 void Parser::CheckStrictModeLValue(Expression* expression, |
| 4555 const char* error, | |
| 4556 bool* ok) { | 4267 bool* ok) { |
| 4557 ASSERT(!top_scope_->is_classic_mode()); | 4268 ASSERT(!scope_->is_classic_mode()); |
| 4558 VariableProxy* lhs = expression != NULL | 4269 VariableProxy* lhs = expression != NULL |
| 4559 ? expression->AsVariableProxy() | 4270 ? expression->AsVariableProxy() |
| 4560 : NULL; | 4271 : NULL; |
| 4561 | 4272 |
| 4562 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4273 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4563 ReportMessage(error, Vector<const char*>::empty()); | 4274 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4564 *ok = false; | 4275 *ok = false; |
| 4565 } | 4276 } |
| 4566 } | 4277 } |
| 4567 | |
| 4568 | |
| 4569 // Checks whether an octal literal was last seen between beg_pos and end_pos. | |
| 4570 // If so, reports an error. Only called for strict mode. | |
| 4571 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | |
| 4572 ScannerBase::Location octal = scanner()->octal_position(); | |
| 4573 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | |
| 4574 ReportMessageAt(octal, "strict_octal_literal"); | |
| 4575 scanner()->clear_octal_position(); | |
| 4576 *ok = false; | |
| 4577 } | |
| 4578 } | |
| 4579 | 4278 |
| 4580 | 4279 |
| 4581 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4280 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4582 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4281 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4583 if (decl != NULL) { | 4282 if (decl != NULL) { |
| 4584 // In harmony mode we treat conflicting variable bindinds as early | 4283 // In harmony mode we treat conflicting variable bindinds as early |
| 4585 // errors. See ES5 16 for a definition of early errors. | 4284 // errors. See ES5 16 for a definition of early errors. |
| 4586 Handle<String> name = decl->proxy()->name(); | 4285 Handle<String> name = decl->proxy()->name(); |
| 4587 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4286 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4588 const char* elms[2] = { "Variable", c_string.get() }; | 4287 const char* elms[2] = { "Variable", c_string.get() }; |
| 4589 Vector<const char*> args(elms, 2); | 4288 Vector<const char*> args(elms, 2); |
| 4590 int position = decl->proxy()->position(); | 4289 int position = decl->proxy()->position(); |
| 4591 ScannerBase::Location location = position == RelocInfo::kNoPosition | 4290 Scanner::Location location = position == RelocInfo::kNoPosition |
| 4592 ? ScannerBase::Location::invalid() | 4291 ? Scanner::Location::invalid() |
| 4593 : ScannerBase::Location(position, position + 1); | 4292 : Scanner::Location(position, position + 1); |
| 4594 ReportMessageAt(location, "redeclaration", args); | 4293 ParserTraits::ReportMessageAt(location, "redeclaration", args); |
| 4595 *ok = false; | 4294 *ok = false; |
| 4596 } | 4295 } |
| 4597 } | 4296 } |
| 4598 | 4297 |
| 4599 | 4298 |
| 4600 // This function reads an identifier name and determines whether or not it | |
| 4601 // is 'get' or 'set'. | |
| 4602 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, | |
| 4603 bool* is_set, | |
| 4604 bool* ok) { | |
| 4605 Handle<String> result = ParseIdentifierName(ok); | |
| 4606 if (!*ok) return Handle<String>(); | |
| 4607 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { | |
| 4608 const char* token = scanner().literal_ascii_string().start(); | |
| 4609 *is_get = strncmp(token, "get", 3) == 0; | |
| 4610 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | |
| 4611 } | |
| 4612 return result; | |
| 4613 } | |
| 4614 | |
| 4615 | |
| 4616 // ---------------------------------------------------------------------------- | 4299 // ---------------------------------------------------------------------------- |
| 4617 // Parser support | 4300 // Parser support |
| 4618 | 4301 |
| 4619 | 4302 |
| 4620 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4303 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| 4621 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4304 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 4622 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4305 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 4623 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 4306 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 4624 return true; | 4307 return true; |
| 4625 } | 4308 } |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5587 if (data >= symbol_data_end_) return -1; | 5270 if (data >= symbol_data_end_) return -1; |
| 5588 input = *data; | 5271 input = *data; |
| 5589 result = (result << 7) | (input & 0x7f); | 5272 result = (result << 7) | (input & 0x7f); |
| 5590 data++; | 5273 data++; |
| 5591 } | 5274 } |
| 5592 *source = data; | 5275 *source = data; |
| 5593 return result; | 5276 return result; |
| 5594 } | 5277 } |
| 5595 | 5278 |
| 5596 | 5279 |
| 5597 // Create a ScannerBase for the preparser to use as input, and preparse the | 5280 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5598 // source. | |
| 5599 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, | 5281 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, |
| 5600 Handle<String> source) { | 5282 Utf16CharacterStream* source) { |
| 5601 CompleteParserRecorder recorder; | 5283 CompleteParserRecorder recorder; |
| 5602 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5284 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
| 5603 source = FlattenGetString(source); | 5285 Scanner scanner(isolate->unicode_cache()); |
| 5604 ScannerBase* scanner = NULL; | |
| 5605 if (source->IsTwoByteRepresentation()) { | |
| 5606 scanner = new ExperimentalScanner<uint16_t>(source, isolate); | |
| 5607 } else { | |
| 5608 scanner = new ExperimentalScanner<uint8_t>(source, isolate); | |
| 5609 } | |
| 5610 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5286 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5611 PreParser preparser(scanner, &recorder, stack_limit); | 5287 PreParser preparser(&scanner, &recorder, stack_limit); |
| 5612 preparser.set_allow_lazy(true); | 5288 preparser.set_allow_lazy(true); |
| 5613 preparser.set_allow_generators(FLAG_harmony_generators); | 5289 preparser.set_allow_generators(FLAG_harmony_generators); |
| 5614 preparser.set_allow_for_of(FLAG_harmony_iteration); | 5290 preparser.set_allow_for_of(FLAG_harmony_iteration); |
| 5615 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | 5291 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
| 5616 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 5292 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 5617 scanner->Init(); | 5293 scanner.Initialize(source); |
| 5618 PreParser::PreParseResult result = preparser.PreParseProgram(); | 5294 PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 5619 if (result == PreParser::kPreParseStackOverflow) { | 5295 if (result == PreParser::kPreParseStackOverflow) { |
| 5620 isolate->StackOverflow(); | 5296 isolate->StackOverflow(); |
| 5621 delete scanner; | |
| 5622 return NULL; | 5297 return NULL; |
| 5623 } | 5298 } |
| 5624 | 5299 |
| 5625 // Extract the accumulated data from the recorder as a single | 5300 // Extract the accumulated data from the recorder as a single |
| 5626 // contiguous vector that we are responsible for disposing. | 5301 // contiguous vector that we are responsible for disposing. |
| 5627 Vector<unsigned> store = recorder.ExtractData(); | 5302 Vector<unsigned> store = recorder.ExtractData(); |
| 5628 delete scanner; | |
| 5629 return new ScriptDataImpl(store); | 5303 return new ScriptDataImpl(store); |
| 5630 } | 5304 } |
| 5631 | 5305 |
| 5632 | 5306 |
| 5633 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5307 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5634 bool multiline, | 5308 bool multiline, |
| 5635 RegExpCompileData* result, | 5309 RegExpCompileData* result, |
| 5636 Zone* zone) { | 5310 Zone* zone) { |
| 5637 ASSERT(result != NULL); | 5311 ASSERT(result != NULL); |
| 5638 RegExpParser parser(input, &result->error, multiline, zone); | 5312 RegExpParser parser(input, &result->error, multiline, zone); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5660 ASSERT(!info()->is_eval()); | 5334 ASSERT(!info()->is_eval()); |
| 5661 if (info()->shared_info()->is_function()) { | 5335 if (info()->shared_info()->is_function()) { |
| 5662 result = ParseLazy(); | 5336 result = ParseLazy(); |
| 5663 } else { | 5337 } else { |
| 5664 result = ParseProgram(); | 5338 result = ParseProgram(); |
| 5665 } | 5339 } |
| 5666 } else { | 5340 } else { |
| 5667 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 5341 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
| 5668 set_pre_parse_data(pre_parse_data); | 5342 set_pre_parse_data(pre_parse_data); |
| 5669 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 5343 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
| 5670 ScannerBase::Location loc = pre_parse_data->MessageLocation(); | 5344 Scanner::Location loc = pre_parse_data->MessageLocation(); |
| 5671 const char* message = pre_parse_data->BuildMessage(); | 5345 const char* message = pre_parse_data->BuildMessage(); |
| 5672 Vector<const char*> args = pre_parse_data->BuildArgs(); | 5346 Vector<const char*> args = pre_parse_data->BuildArgs(); |
| 5673 ReportMessageAt(loc, message, args); | 5347 ParserTraits::ReportMessageAt(loc, message, args); |
| 5674 DeleteArray(message); | 5348 DeleteArray(message); |
| 5675 for (int i = 0; i < args.length(); i++) { | 5349 for (int i = 0; i < args.length(); i++) { |
| 5676 DeleteArray(args[i]); | 5350 DeleteArray(args[i]); |
| 5677 } | 5351 } |
| 5678 DeleteArray(args.start()); | 5352 DeleteArray(args.start()); |
| 5679 ASSERT(info()->isolate()->has_pending_exception()); | 5353 ASSERT(info()->isolate()->has_pending_exception()); |
| 5680 } else { | 5354 } else { |
| 5681 result = ParseProgram(); | 5355 result = ParseProgram(); |
| 5682 } | 5356 } |
| 5683 } | 5357 } |
| 5684 info()->SetFunction(result); | 5358 info()->SetFunction(result); |
| 5685 return (result != NULL); | 5359 return (result != NULL); |
| 5686 } | 5360 } |
| 5687 | 5361 |
| 5688 | |
| 5689 void Parser::SetScannerFlags() { | |
| 5690 scanner_->SetHarmonyScoping(allow_harmony_scoping_); | |
| 5691 scanner_->SetHarmonyModules(allow_harmony_modules_); | |
| 5692 scanner_->SetHarmonyNumericLiterals(allow_harmony_numeric_literals_); | |
| 5693 } | |
| 5694 | |
| 5695 } } // namespace v8::internal | 5362 } } // namespace v8::internal |
| OLD | NEW |