| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "api.h" | 7 #include "api.h" |
| 8 #include "ast.h" | 8 #include "ast.h" |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "char-predicates-inl.h" | 10 #include "char-predicates-inl.h" |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 return store_[PreparseDataConstants::kHeaderSize + position]; | 319 return store_[PreparseDataConstants::kHeaderSize + position]; |
| 320 } | 320 } |
| 321 | 321 |
| 322 | 322 |
| 323 unsigned* ScriptData::ReadAddress(int position) const { | 323 unsigned* ScriptData::ReadAddress(int position) const { |
| 324 return &store_[PreparseDataConstants::kHeaderSize + position]; | 324 return &store_[PreparseDataConstants::kHeaderSize + position]; |
| 325 } | 325 } |
| 326 | 326 |
| 327 | 327 |
| 328 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 328 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
| 329 Scope* result = new(zone()) Scope(parent, scope_type, zone()); | 329 ASSERT(symbol_table_); |
| 330 Scope* result = new(zone()) Scope(parent, scope_type, symbol_table_, zone()); |
| 330 result->Initialize(); | 331 result->Initialize(); |
| 331 return result; | 332 return result; |
| 332 } | 333 } |
| 333 | 334 |
| 334 | 335 |
| 335 // ---------------------------------------------------------------------------- | 336 // ---------------------------------------------------------------------------- |
| 336 // Target is a support class to facilitate manipulation of the | 337 // Target is a support class to facilitate manipulation of the |
| 337 // Parser's target_stack_ (the stack of potential 'break' and | 338 // Parser's target_stack_ (the stack of potential 'break' and |
| 338 // 'continue' statement targets). Upon construction, a new target is | 339 // 'continue' statement targets). Upon construction, a new target is |
| 339 // added; it is removed upon destruction. | 340 // added; it is removed upon destruction. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 393 |
| 393 #define CHECK_FAILED /**/); \ | 394 #define CHECK_FAILED /**/); \ |
| 394 if (failed_) return NULL; \ | 395 if (failed_) return NULL; \ |
| 395 ((void)0 | 396 ((void)0 |
| 396 #define DUMMY ) // to make indentation work | 397 #define DUMMY ) // to make indentation work |
| 397 #undef DUMMY | 398 #undef DUMMY |
| 398 | 399 |
| 399 // ---------------------------------------------------------------------------- | 400 // ---------------------------------------------------------------------------- |
| 400 // Implementation of Parser | 401 // Implementation of Parser |
| 401 | 402 |
| 402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 403 bool ParserTraits::IsEvalOrArguments( |
| 403 Factory* factory = parser_->isolate()->factory(); | 404 ParserSymbolTable::Symbol* identifier) const { |
| 404 return identifier.is_identical_to(factory->eval_string()) | 405 return identifier == parser_->symbol_table_->eval_string() || |
| 405 || identifier.is_identical_to(factory->arguments_string()); | 406 identifier == parser_->symbol_table_->arguments_string(); |
| 406 } | 407 } |
| 407 | 408 |
| 408 | 409 |
| 409 bool ParserTraits::IsThisProperty(Expression* expression) { | 410 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 410 ASSERT(expression != NULL); | 411 ASSERT(expression != NULL); |
| 411 Property* property = expression->AsProperty(); | 412 Property* property = expression->AsProperty(); |
| 412 return property != NULL && | 413 return property != NULL && |
| 413 property->obj()->AsVariableProxy() != NULL && | 414 property->obj()->AsVariableProxy() != NULL && |
| 414 property->obj()->AsVariableProxy()->is_this(); | 415 property->obj()->AsVariableProxy()->is_this(); |
| 415 } | 416 } |
| 416 | 417 |
| 417 | 418 |
| 418 bool ParserTraits::IsIdentifier(Expression* expression) { | 419 bool ParserTraits::IsIdentifier(Expression* expression) { |
| 419 VariableProxy* operand = expression->AsVariableProxy(); | 420 VariableProxy* operand = expression->AsVariableProxy(); |
| 420 return operand != NULL && !operand->is_this(); | 421 return operand != NULL && !operand->is_this(); |
| 421 } | 422 } |
| 422 | 423 |
| 423 | 424 |
| 424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, | 425 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
| 425 Expression* expression) { | 426 Expression* expression) { |
| 426 if (expression->IsPropertyName()) { | 427 if (expression->IsPropertyName()) { |
| 427 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); | 428 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
| 428 } else { | 429 } else { |
| 429 fni->PushLiteralName( | 430 fni->PushLiteralName(parser_->symbol_table_->anonymous_function_string()); |
| 430 parser_->isolate()->factory()->anonymous_function_string()); | |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 | 433 |
| 434 | 434 |
| 435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 436 Expression* right) { | 436 Expression* right) { |
| 437 ASSERT(left != NULL); | 437 ASSERT(left != NULL); |
| 438 if (left->AsProperty() != NULL && | 438 if (left->AsProperty() != NULL && |
| 439 right->AsFunctionLiteral() != NULL) { | 439 right->AsFunctionLiteral() != NULL) { |
| 440 right->AsFunctionLiteral()->set_pretenure(); | 440 right->AsFunctionLiteral()->set_pretenure(); |
| 441 } | 441 } |
| 442 } | 442 } |
| 443 | 443 |
| 444 | 444 |
| 445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
| 446 Scope* scope) { | 446 Scope* scope) { |
| 447 VariableProxy* callee = expression->AsVariableProxy(); | 447 VariableProxy* callee = expression->AsVariableProxy(); |
| 448 if (callee != NULL && | 448 if (callee != NULL && |
| 449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) { | 449 callee->raw_name() == parser_->symbol_table_->eval_string()) { |
| 450 scope->DeclarationScope()->RecordEvalCall(); | 450 scope->DeclarationScope()->RecordEvalCall(); |
| 451 } | 451 } |
| 452 } | 452 } |
| 453 | 453 |
| 454 | 454 |
| 455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 456 VariableProxy* proxy = expression != NULL | 456 VariableProxy* proxy = expression != NULL |
| 457 ? expression->AsVariableProxy() | 457 ? expression->AsVariableProxy() |
| 458 : NULL; | 458 : NULL; |
| 459 if (proxy != NULL) proxy->MarkAsLValue(); | 459 if (proxy != NULL) proxy->MarkAsLValue(); |
| 460 return expression; | 460 return expression; |
| 461 } | 461 } |
| 462 | 462 |
| 463 | 463 |
| 464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
| 465 Expression** x, Expression* y, Token::Value op, int pos, | 465 Expression** x, Expression* y, Token::Value op, int pos, |
| 466 AstNodeFactory<AstConstructionVisitor>* factory) { | 466 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && | 467 // FIXME: this needs to change when it cannot use handles. |
| 468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 468 if ((*x)->AsLiteral() && !(*x)->AsLiteral()->valueIfNotString().is_null() && |
| 469 double x_val = (*x)->AsLiteral()->value()->Number(); | 469 (*x)->AsLiteral()->valueIfNotString()->IsNumber() && y->AsLiteral() && |
| 470 double y_val = y->AsLiteral()->value()->Number(); | 470 !y->AsLiteral()->valueIfNotString().is_null() && |
| 471 y->AsLiteral()->valueIfNotString()->IsNumber()) { |
| 472 double x_val = (*x)->AsLiteral()->valueIfNotString()->Number(); |
| 473 double y_val = y->AsLiteral()->valueIfNotString()->Number(); |
| 471 switch (op) { | 474 switch (op) { |
| 472 case Token::ADD: | 475 case Token::ADD: |
| 473 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 476 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| 474 return true; | 477 return true; |
| 475 case Token::SUB: | 478 case Token::SUB: |
| 476 *x = factory->NewNumberLiteral(x_val - y_val, pos); | 479 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
| 477 return true; | 480 return true; |
| 478 case Token::MUL: | 481 case Token::MUL: |
| 479 *x = factory->NewNumberLiteral(x_val * y_val, pos); | 482 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
| 480 return true; | 483 return true; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 } | 521 } |
| 519 } | 522 } |
| 520 return false; | 523 return false; |
| 521 } | 524 } |
| 522 | 525 |
| 523 | 526 |
| 524 Expression* ParserTraits::BuildUnaryExpression( | 527 Expression* ParserTraits::BuildUnaryExpression( |
| 525 Expression* expression, Token::Value op, int pos, | 528 Expression* expression, Token::Value op, int pos, |
| 526 AstNodeFactory<AstConstructionVisitor>* factory) { | 529 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 527 ASSERT(expression != NULL); | 530 ASSERT(expression != NULL); |
| 528 if (expression->AsLiteral() != NULL) { | 531 // FIXME: This needs to change when numbers and booleans are no longer |
| 529 Handle<Object> literal = expression->AsLiteral()->value(); | 532 // handles. |
| 533 // FIXME: The !"foo" shortcut doesn't work atm. |
| 534 if (expression->AsLiteral() != NULL && |
| 535 !expression->AsLiteral()->valueIfNotString().is_null()) { |
| 536 Handle<Object> literal = expression->AsLiteral()->valueIfNotString(); |
| 530 if (op == Token::NOT) { | 537 if (op == Token::NOT) { |
| 531 // Convert the literal to a boolean condition and negate it. | 538 // Convert the literal to a boolean condition and negate it. |
| 532 bool condition = literal->BooleanValue(); | 539 bool condition = literal->BooleanValue(); |
| 533 Handle<Object> result = | 540 Handle<Object> result = |
| 534 parser_->isolate()->factory()->ToBoolean(!condition); | 541 parser_->isolate()->factory()->ToBoolean(!condition); |
| 535 return factory->NewLiteral(result, pos); | 542 return factory->NewLiteral(result, pos); |
| 536 } else if (literal->IsNumber()) { | 543 } else if (literal->IsNumber()) { |
| 537 // Compute some expressions involving only number literals. | 544 // Compute some expressions involving only number literals. |
| 538 double value = literal->Number(); | 545 double value = literal->Number(); |
| 539 switch (op) { | 546 switch (op) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 561 // ...and one more time for '~foo' => 'foo^(~0)'. | 568 // ...and one more time for '~foo' => 'foo^(~0)'. |
| 562 if (op == Token::BIT_NOT) { | 569 if (op == Token::BIT_NOT) { |
| 563 return factory->NewBinaryOperation( | 570 return factory->NewBinaryOperation( |
| 564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 571 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
| 565 } | 572 } |
| 566 return factory->NewUnaryOperation(op, expression, pos); | 573 return factory->NewUnaryOperation(op, expression, pos); |
| 567 } | 574 } |
| 568 | 575 |
| 569 | 576 |
| 570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { | 577 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
| 571 return NewThrowError( | 578 return NewThrowError(parser_->symbol_table_->make_reference_error_string(), |
| 572 parser_->isolate()->factory()->MakeReferenceError_string(), | 579 message, NULL, pos); |
| 573 message, HandleVector<Object>(NULL, 0), pos); | |
| 574 } | 580 } |
| 575 | 581 |
| 576 | 582 |
| 577 Expression* ParserTraits::NewThrowSyntaxError( | 583 Expression* ParserTraits::NewThrowSyntaxError( |
| 578 const char* message, Handle<Object> arg, int pos) { | 584 const char* message, ParserSymbolTable::Symbol* arg, int pos) { |
| 579 int argc = arg.is_null() ? 0 : 1; | 585 return NewThrowError(parser_->symbol_table_->make_syntax_error_string(), |
| 580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 586 message, arg, pos); |
| 581 return NewThrowError( | |
| 582 parser_->isolate()->factory()->MakeSyntaxError_string(), | |
| 583 message, arguments, pos); | |
| 584 } | 587 } |
| 585 | 588 |
| 586 | 589 |
| 587 Expression* ParserTraits::NewThrowTypeError( | 590 Expression* ParserTraits::NewThrowTypeError( |
| 588 const char* message, Handle<Object> arg, int pos) { | 591 const char* message, ParserSymbolTable::Symbol* arg, int pos) { |
| 589 int argc = arg.is_null() ? 0 : 1; | 592 return NewThrowError(parser_->symbol_table_->make_type_error_string(), |
| 590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 593 message, arg, pos); |
| 591 return NewThrowError( | |
| 592 parser_->isolate()->factory()->MakeTypeError_string(), | |
| 593 message, arguments, pos); | |
| 594 } | 594 } |
| 595 | 595 |
| 596 | 596 |
| 597 Expression* ParserTraits::NewThrowError( | 597 Expression* ParserTraits::NewThrowError( |
| 598 Handle<String> constructor, const char* message, | 598 ParserSymbolTable::Symbol* constructor, const char* message, |
| 599 Vector<Handle<Object> > arguments, int pos) { | 599 ParserSymbolTable::Symbol* arg, int pos) { |
| 600 Zone* zone = parser_->zone(); | 600 Zone* zone = parser_->zone(); |
| 601 Factory* factory = parser_->isolate()->factory(); | 601 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(arg != NULL ? 2
: 1, zone); |
| 602 int argc = arguments.length(); | 602 ParserSymbolTable::Symbol* type = |
| 603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); | 603 parser_->symbol_table_->GetOneByteSymbol(Vector<const uint8_t>( |
| 604 for (int i = 0; i < argc; i++) { | 604 reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
| 605 Handle<Object> element = arguments[i]; | 605 args->Add(parser_->factory()->NewLiteral(type, pos), zone); |
| 606 if (!element.is_null()) { | 606 if (arg != NULL) { |
| 607 elements->set(i, *element); | 607 ZoneList<ParserSymbolTable::Symbol*>* array = |
| 608 } | 608 new (zone) ZoneList<ParserSymbolTable::Symbol*>(1, zone); |
| 609 array->Add(arg, zone); |
| 610 args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
| 609 } | 611 } |
| 610 Handle<JSArray> array = | |
| 611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); | |
| 612 | |
| 613 ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone); | |
| 614 Handle<String> type = factory->InternalizeUtf8String(message); | |
| 615 args->Add(parser_->factory()->NewLiteral(type, pos), zone); | |
| 616 args->Add(parser_->factory()->NewLiteral(array, pos), zone); | |
| 617 CallRuntime* call_constructor = | 612 CallRuntime* call_constructor = |
| 618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | 613 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
| 619 return parser_->factory()->NewThrow(call_constructor, pos); | 614 return parser_->factory()->NewThrow(call_constructor, pos); |
| 620 } | 615 } |
| 621 | 616 |
| 622 | 617 |
| 623 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 618 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 624 const char* message, | 619 const char* message, |
| 625 const char* arg, | 620 const char* char_arg, |
| 626 bool is_reference_error) { | 621 bool is_reference_error) { |
| 627 if (parser_->stack_overflow()) { | 622 if (parser_->stack_overflow()) { |
| 628 // Suppress the error message (syntax error or such) in the presence of a | 623 // Suppress the error message (syntax error or such) in the presence of a |
| 629 // stack overflow. The isolate allows only one pending exception at at time | 624 // stack overflow. The isolate allows only one pending exception at at time |
| 630 // and we want to report the stack overflow later. | 625 // and we want to report the stack overflow later. |
| 631 return; | 626 return; |
| 632 } | 627 } |
| 633 MessageLocation location(parser_->script_, | 628 parser_->has_pending_error_ = true; |
| 634 source_location.beg_pos, | 629 parser_->pending_location_ = source_location; |
| 635 source_location.end_pos); | 630 parser_->pending_message_ = message; |
| 636 Factory* factory = parser_->isolate()->factory(); | 631 parser_->pending_char_arg_ = char_arg; |
| 637 Handle<FixedArray> elements = factory->NewFixedArray(arg == NULL ? 0 : 1); | 632 parser_->pending_arg_ = NULL; |
| 638 if (arg != NULL) { | 633 parser_->pending_is_reference_error_ = is_reference_error; |
| 639 Handle<String> arg_string = | |
| 640 factory->NewStringFromUtf8(CStrVector(arg)).ToHandleChecked(); | |
| 641 elements->set(0, *arg_string); | |
| 642 } | |
| 643 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 644 Handle<Object> result = is_reference_error | |
| 645 ? factory->NewReferenceError(message, array) | |
| 646 : factory->NewSyntaxError(message, array); | |
| 647 parser_->isolate()->Throw(*result, &location); | |
| 648 } | |
| 649 | |
| 650 | |
| 651 void ParserTraits::ReportMessage(const char* message, | |
| 652 MaybeHandle<String> arg, | |
| 653 bool is_reference_error) { | |
| 654 Scanner::Location source_location = parser_->scanner()->location(); | |
| 655 ReportMessageAt(source_location, message, arg, is_reference_error); | |
| 656 } | 634 } |
| 657 | 635 |
| 658 | 636 |
| 659 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 637 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 660 const char* message, | 638 const char* message, |
| 661 MaybeHandle<String> arg, | 639 ParserSymbolTable::Symbol* arg, |
| 662 bool is_reference_error) { | 640 bool is_reference_error) { |
| 663 if (parser_->stack_overflow()) { | 641 if (parser_->stack_overflow()) { |
| 664 // Suppress the error message (syntax error or such) in the presence of a | 642 // Suppress the error message (syntax error or such) in the presence of a |
| 665 // stack overflow. The isolate allows only one pending exception at at time | 643 // stack overflow. The isolate allows only one pending exception at at time |
| 666 // and we want to report the stack overflow later. | 644 // and we want to report the stack overflow later. |
| 667 return; | 645 return; |
| 668 } | 646 } |
| 669 MessageLocation location(parser_->script_, | 647 parser_->has_pending_error_ = true; |
| 670 source_location.beg_pos, | 648 parser_->pending_location_ = source_location; |
| 671 source_location.end_pos); | 649 parser_->pending_message_ = message; |
| 672 Factory* factory = parser_->isolate()->factory(); | 650 parser_->pending_char_arg_ = NULL; |
| 673 Handle<FixedArray> elements = factory->NewFixedArray(arg.is_null() ? 0 : 1); | 651 parser_->pending_arg_ = arg; |
| 674 if (!arg.is_null()) { | 652 parser_->pending_is_reference_error_ = is_reference_error; |
| 675 elements->set(0, *(arg.ToHandleChecked())); | |
| 676 } | |
| 677 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 678 Handle<Object> result = is_reference_error | |
| 679 ? factory->NewReferenceError(message, array) | |
| 680 : factory->NewSyntaxError(message, array); | |
| 681 parser_->isolate()->Throw(*result, &location); | |
| 682 } | 653 } |
| 683 | 654 |
| 684 | 655 |
| 685 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 656 void ParserTraits::ReportMessage(const char* message, |
| 686 Handle<String> result = | 657 const char* char_arg, |
| 687 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); | 658 bool is_reference_error) { |
| 688 ASSERT(!result.is_null()); | 659 Scanner::Location source_location = parser_->scanner()->location(); |
| 689 return result; | 660 ReportMessageAt(source_location, message, char_arg, is_reference_error); |
| 690 } | 661 } |
| 691 | 662 |
| 692 | 663 |
| 693 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 664 void ParserTraits::ReportMessage(const char* message, |
| 694 PretenureFlag tenured) { | 665 ParserSymbolTable::Symbol* arg, |
| 695 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | 666 bool is_reference_error) { |
| 667 Scanner::Location source_location = parser_->scanner()->location(); |
| 668 ReportMessageAt(source_location, message, arg, is_reference_error); |
| 696 } | 669 } |
| 697 | 670 |
| 698 | 671 |
| 672 ParserSymbolTable::Symbol* ParserTraits::GetSymbol(Scanner* scanner) { |
| 673 return parser_->scanner()->CurrentString(parser_->symbol_table_); |
| 674 } |
| 675 |
| 676 |
| 677 ParserSymbolTable::Symbol* ParserTraits::GetNextSymbol(Scanner* scanner) { |
| 678 return parser_->scanner()->NextString(parser_->symbol_table_); |
| 679 } |
| 680 |
| 681 |
| 699 Expression* ParserTraits::ThisExpression( | 682 Expression* ParserTraits::ThisExpression( |
| 700 Scope* scope, | 683 Scope* scope, |
| 701 AstNodeFactory<AstConstructionVisitor>* factory) { | 684 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 702 return factory->NewVariableProxy(scope->receiver()); | 685 return factory->NewVariableProxy(scope->receiver()); |
| 703 } | 686 } |
| 704 | 687 |
| 705 | 688 |
| 706 Literal* ParserTraits::ExpressionFromLiteral( | 689 Literal* ParserTraits::ExpressionFromLiteral( |
| 707 Token::Value token, int pos, | 690 Token::Value token, int pos, |
| 708 Scanner* scanner, | 691 Scanner* scanner, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 720 return factory->NewNumberLiteral(value, pos); | 703 return factory->NewNumberLiteral(value, pos); |
| 721 } | 704 } |
| 722 default: | 705 default: |
| 723 ASSERT(false); | 706 ASSERT(false); |
| 724 } | 707 } |
| 725 return NULL; | 708 return NULL; |
| 726 } | 709 } |
| 727 | 710 |
| 728 | 711 |
| 729 Expression* ParserTraits::ExpressionFromIdentifier( | 712 Expression* ParserTraits::ExpressionFromIdentifier( |
| 730 Handle<String> name, int pos, Scope* scope, | 713 ParserSymbolTable::Symbol* name, int pos, Scope* scope, |
| 731 AstNodeFactory<AstConstructionVisitor>* factory) { | 714 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 732 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 715 if (parser_->fni_ != NULL) { |
| 716 parser_->fni_->PushVariableName(name); |
| 717 } |
| 733 // The name may refer to a module instance object, so its type is unknown. | 718 // The name may refer to a module instance object, so its type is unknown. |
| 734 #ifdef DEBUG | 719 #ifdef DEBUG |
| 735 if (FLAG_print_interface_details) | 720 if (FLAG_print_interface_details) { |
| 736 PrintF("# Variable %s ", name->ToAsciiArray()); | 721 PrintF("# Variable %.*s ", name->literal_bytes.length(), |
| 722 name->literal_bytes.start()); |
| 723 } |
| 737 #endif | 724 #endif |
| 738 Interface* interface = Interface::NewUnknown(parser_->zone()); | 725 Interface* interface = Interface::NewUnknown(parser_->zone()); |
| 739 return scope->NewUnresolved(factory, name, interface, pos); | 726 return scope->NewUnresolved(factory, name, interface, pos); |
| 740 } | 727 } |
| 741 | 728 |
| 742 | 729 |
| 743 Expression* ParserTraits::ExpressionFromString( | 730 Expression* ParserTraits::ExpressionFromString( |
| 744 int pos, Scanner* scanner, | 731 int pos, Scanner* scanner, |
| 745 AstNodeFactory<AstConstructionVisitor>* factory) { | 732 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 746 Handle<String> symbol = GetSymbol(scanner); | 733 ParserSymbolTable::Symbol* symbol = GetSymbol(scanner); |
| 747 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 734 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 748 return factory->NewLiteral(symbol, pos); | 735 return factory->NewLiteral(symbol, pos); |
| 749 } | 736 } |
| 750 | 737 |
| 751 | 738 |
| 752 Literal* ParserTraits::GetLiteralTheHole( | 739 Literal* ParserTraits::GetLiteralTheHole( |
| 753 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 740 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 754 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 741 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| 755 RelocInfo::kNoPosition); | 742 RelocInfo::kNoPosition); |
| 756 } | 743 } |
| 757 | 744 |
| 758 | 745 |
| 759 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 746 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 760 return parser_->ParseV8Intrinsic(ok); | 747 return parser_->ParseV8Intrinsic(ok); |
| 761 } | 748 } |
| 762 | 749 |
| 763 | 750 |
| 764 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 751 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| 765 Handle<String> name, | 752 ParserSymbolTable::Symbol* name, |
| 766 Scanner::Location function_name_location, | 753 Scanner::Location function_name_location, |
| 767 bool name_is_strict_reserved, | 754 bool name_is_strict_reserved, |
| 768 bool is_generator, | 755 bool is_generator, |
| 769 int function_token_position, | 756 int function_token_position, |
| 770 FunctionLiteral::FunctionType type, | 757 FunctionLiteral::FunctionType type, |
| 771 bool* ok) { | 758 bool* ok) { |
| 772 return parser_->ParseFunctionLiteral(name, function_name_location, | 759 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 773 name_is_strict_reserved, is_generator, | 760 name_is_strict_reserved, is_generator, |
| 774 function_token_position, type, ok); | 761 function_token_position, type, ok); |
| 775 } | 762 } |
| 776 | 763 |
| 777 | 764 |
| 778 Parser::Parser(CompilationInfo* info) | 765 Parser::Parser(CompilationInfo* info) |
| 779 : ParserBase<ParserTraits>(&scanner_, | 766 : ParserBase<ParserTraits>(&scanner_, |
| 780 info->isolate()->stack_guard()->real_climit(), | 767 info->isolate()->stack_guard()->real_climit(), |
| 781 info->extension(), | 768 info->extension(), |
| 782 NULL, | 769 NULL, |
| 783 info->zone(), | 770 info->zone(), |
| 784 this), | 771 this), |
| 785 isolate_(info->isolate()), | 772 isolate_(info->isolate()), |
| 786 script_(info->script()), | 773 script_(info->script()), |
| 787 scanner_(isolate_->unicode_cache()), | 774 scanner_(isolate_->unicode_cache()), |
| 788 reusable_preparser_(NULL), | 775 reusable_preparser_(NULL), |
| 789 original_scope_(NULL), | 776 original_scope_(NULL), |
| 790 target_stack_(NULL), | 777 target_stack_(NULL), |
| 791 cached_data_(NULL), | 778 cached_data_(NULL), |
| 792 cached_data_mode_(NO_CACHED_DATA), | 779 cached_data_mode_(NO_CACHED_DATA), |
| 793 info_(info) { | 780 symbol_table_(NULL), |
| 781 info_(info), |
| 782 has_pending_error_(false), |
| 783 pending_message_(NULL), |
| 784 pending_arg_(NULL), |
| 785 pending_char_arg_(NULL) { |
| 794 ASSERT(!script_.is_null()); | 786 ASSERT(!script_.is_null()); |
| 795 isolate_->set_ast_node_id(0); | 787 isolate_->set_ast_node_id(0); |
| 796 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 788 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 797 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 789 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 798 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 790 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 799 set_allow_lazy(false); // Must be explicitly enabled. | 791 set_allow_lazy(false); // Must be explicitly enabled. |
| 800 set_allow_generators(FLAG_harmony_generators); | 792 set_allow_generators(FLAG_harmony_generators); |
| 801 set_allow_for_of(FLAG_harmony_iteration); | 793 set_allow_for_of(FLAG_harmony_iteration); |
| 802 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 794 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 803 } | 795 } |
| 804 | 796 |
| 805 | 797 |
| 806 FunctionLiteral* Parser::ParseProgram() { | 798 FunctionLiteral* Parser::ParseProgram() { |
| 807 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 799 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 808 // see comment for HistogramTimerScope class. | 800 // see comment for HistogramTimerScope class. |
| 809 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 801 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 810 Handle<String> source(String::cast(script_->source())); | 802 Handle<String> source(String::cast(script_->source())); |
| 811 isolate()->counters()->total_parse_size()->Increment(source->length()); | 803 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 812 ElapsedTimer timer; | 804 ElapsedTimer timer; |
| 813 if (FLAG_trace_parse) { | 805 if (FLAG_trace_parse) { |
| 814 timer.Start(); | 806 timer.Start(); |
| 815 } | 807 } |
| 816 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 808 fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone()); |
| 817 | 809 |
| 818 // Initialize parser state. | 810 // Initialize parser state. |
| 819 CompleteParserRecorder recorder; | 811 CompleteParserRecorder recorder; |
| 820 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 812 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 821 log_ = &recorder; | 813 log_ = &recorder; |
| 822 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 814 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 823 (*cached_data_)->Initialize(); | 815 (*cached_data_)->Initialize(); |
| 824 } | 816 } |
| 825 | 817 |
| 826 source = String::Flatten(source); | 818 source = String::Flatten(source); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 } | 853 } |
| 862 return result; | 854 return result; |
| 863 } | 855 } |
| 864 | 856 |
| 865 | 857 |
| 866 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 858 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 867 Handle<String> source) { | 859 Handle<String> source) { |
| 868 ASSERT(scope_ == NULL); | 860 ASSERT(scope_ == NULL); |
| 869 ASSERT(target_stack_ == NULL); | 861 ASSERT(target_stack_ == NULL); |
| 870 | 862 |
| 871 Handle<String> no_name = isolate()->factory()->empty_string(); | 863 ParserSymbolTable::Symbol* no_name = symbol_table_->empty_string(); |
| 872 | 864 |
| 873 FunctionLiteral* result = NULL; | 865 FunctionLiteral* result = NULL; |
| 874 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 866 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 875 info->SetGlobalScope(scope); | 867 info->SetGlobalScope(scope); |
| 876 if (!info->context().is_null()) { | 868 if (!info->context().is_null()) { |
| 877 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 869 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 870 symbol_table_->AlwaysInternalize(isolate()); |
| 878 } | 871 } |
| 879 original_scope_ = scope; | 872 original_scope_ = scope; |
| 880 if (info->is_eval()) { | 873 if (info->is_eval()) { |
| 881 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { | 874 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
| 882 scope = NewScope(scope, EVAL_SCOPE); | 875 scope = NewScope(scope, EVAL_SCOPE); |
| 883 } | 876 } |
| 884 } else if (info->is_global()) { | 877 } else if (info->is_global()) { |
| 885 scope = NewScope(scope, GLOBAL_SCOPE); | 878 scope = NewScope(scope, GLOBAL_SCOPE); |
| 886 } | 879 } |
| 887 scope->set_start_position(0); | 880 scope->set_start_position(0); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 915 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 908 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 916 if (body->length() != 1 || | 909 if (body->length() != 1 || |
| 917 !body->at(0)->IsExpressionStatement() || | 910 !body->at(0)->IsExpressionStatement() || |
| 918 !body->at(0)->AsExpressionStatement()-> | 911 !body->at(0)->AsExpressionStatement()-> |
| 919 expression()->IsFunctionLiteral()) { | 912 expression()->IsFunctionLiteral()) { |
| 920 ReportMessage("single_function_literal"); | 913 ReportMessage("single_function_literal"); |
| 921 ok = false; | 914 ok = false; |
| 922 } | 915 } |
| 923 } | 916 } |
| 924 | 917 |
| 918 symbol_table_->Internalize(isolate()); |
| 919 |
| 925 if (ok) { | 920 if (ok) { |
| 926 result = factory()->NewFunctionLiteral( | 921 result = factory()->NewFunctionLiteral( |
| 927 no_name, | 922 no_name, |
| 928 scope_, | 923 scope_, |
| 929 body, | 924 body, |
| 930 function_state.materialized_literal_count(), | 925 function_state.materialized_literal_count(), |
| 931 function_state.expected_property_count(), | 926 function_state.expected_property_count(), |
| 932 function_state.handler_count(), | 927 function_state.handler_count(), |
| 933 0, | 928 0, |
| 934 FunctionLiteral::kNoDuplicateParameters, | 929 FunctionLiteral::kNoDuplicateParameters, |
| 935 FunctionLiteral::ANONYMOUS_EXPRESSION, | 930 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 936 FunctionLiteral::kGlobalOrEval, | 931 FunctionLiteral::kGlobalOrEval, |
| 937 FunctionLiteral::kNotParenthesized, | 932 FunctionLiteral::kNotParenthesized, |
| 938 FunctionLiteral::kNotGenerator, | 933 FunctionLiteral::kNotGenerator, |
| 939 0); | 934 0); |
| 940 result->set_ast_properties(factory()->visitor()->ast_properties()); | 935 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 941 result->set_dont_optimize_reason( | 936 result->set_dont_optimize_reason( |
| 942 factory()->visitor()->dont_optimize_reason()); | 937 factory()->visitor()->dont_optimize_reason()); |
| 938 |
| 943 } else if (stack_overflow()) { | 939 } else if (stack_overflow()) { |
| 944 isolate()->StackOverflow(); | 940 isolate()->StackOverflow(); |
| 941 } else { |
| 942 CheckPendingError(); |
| 945 } | 943 } |
| 946 } | 944 } |
| 947 | 945 |
| 948 // Make sure the target stack is empty. | 946 // Make sure the target stack is empty. |
| 949 ASSERT(target_stack_ == NULL); | 947 ASSERT(target_stack_ == NULL); |
| 950 | 948 |
| 951 return result; | 949 return result; |
| 952 } | 950 } |
| 953 | 951 |
| 954 | 952 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 } | 985 } |
| 988 | 986 |
| 989 | 987 |
| 990 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 988 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 991 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 989 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 992 scanner_.Initialize(source); | 990 scanner_.Initialize(source); |
| 993 ASSERT(scope_ == NULL); | 991 ASSERT(scope_ == NULL); |
| 994 ASSERT(target_stack_ == NULL); | 992 ASSERT(target_stack_ == NULL); |
| 995 | 993 |
| 996 Handle<String> name(String::cast(shared_info->name())); | 994 Handle<String> name(String::cast(shared_info->name())); |
| 997 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 995 fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone()); |
| 998 fni_->PushEnclosingName(name); | 996 ParserSymbolTable::Symbol* raw_name = symbol_table_->GetSymbol(name); |
| 997 fni_->PushEnclosingName(raw_name); |
| 999 | 998 |
| 1000 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 999 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1001 | 1000 |
| 1002 // Place holder for the result. | 1001 // Place holder for the result. |
| 1003 FunctionLiteral* result = NULL; | 1002 FunctionLiteral* result = NULL; |
| 1004 | 1003 |
| 1005 { | 1004 { |
| 1006 // Parse the function literal. | 1005 // Parse the function literal. |
| 1007 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 1006 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 1008 info()->SetGlobalScope(scope); | 1007 info()->SetGlobalScope(scope); |
| 1009 if (!info()->closure().is_null()) { | 1008 if (!info()->closure().is_null()) { |
| 1010 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 1009 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 1011 zone()); | 1010 zone()); |
| 1012 } | 1011 } |
| 1013 original_scope_ = scope; | 1012 original_scope_ = scope; |
| 1014 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 1013 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 1015 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1014 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| 1016 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 1015 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
| 1017 scope->SetStrictMode(shared_info->strict_mode()); | 1016 scope->SetStrictMode(shared_info->strict_mode()); |
| 1018 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1017 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 1019 ? (shared_info->is_anonymous() | 1018 ? (shared_info->is_anonymous() |
| 1020 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1019 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 1021 : FunctionLiteral::NAMED_EXPRESSION) | 1020 : FunctionLiteral::NAMED_EXPRESSION) |
| 1022 : FunctionLiteral::DECLARATION; | 1021 : FunctionLiteral::DECLARATION; |
| 1023 bool ok = true; | 1022 bool ok = true; |
| 1024 result = ParseFunctionLiteral(name, | 1023 result = ParseFunctionLiteral(raw_name, |
| 1025 Scanner::Location::invalid(), | 1024 Scanner::Location::invalid(), |
| 1026 false, // Strict mode name already checked. | 1025 false, // Strict mode name already checked. |
| 1027 shared_info->is_generator(), | 1026 shared_info->is_generator(), |
| 1028 RelocInfo::kNoPosition, | 1027 RelocInfo::kNoPosition, |
| 1029 function_type, | 1028 function_type, |
| 1030 &ok); | 1029 &ok); |
| 1031 // Make sure the results agree. | 1030 // Make sure the results agree. |
| 1032 ASSERT(ok == (result != NULL)); | 1031 ASSERT(ok == (result != NULL)); |
| 1032 |
| 1033 // Start using the heap (before scope goes out of scope). |
| 1034 symbol_table_->Internalize(isolate()); |
| 1033 } | 1035 } |
| 1034 | 1036 |
| 1035 // Make sure the target stack is empty. | 1037 // Make sure the target stack is empty. |
| 1036 ASSERT(target_stack_ == NULL); | 1038 ASSERT(target_stack_ == NULL); |
| 1037 | 1039 |
| 1038 if (result == NULL) { | 1040 if (result == NULL) { |
| 1039 if (stack_overflow()) isolate()->StackOverflow(); | 1041 if (stack_overflow()) { |
| 1042 isolate()->StackOverflow(); |
| 1043 } else { |
| 1044 CheckPendingError(); |
| 1045 } |
| 1040 } else { | 1046 } else { |
| 1041 Handle<String> inferred_name(shared_info->inferred_name()); | 1047 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1042 result->set_inferred_name(inferred_name); | 1048 result->set_inferred_name(inferred_name); |
| 1043 } | 1049 } |
| 1044 return result; | 1050 return result; |
| 1045 } | 1051 } |
| 1046 | 1052 |
| 1047 | 1053 |
| 1048 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1054 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1049 int end_token, | 1055 int end_token, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1079 continue; | 1085 continue; |
| 1080 } | 1086 } |
| 1081 | 1087 |
| 1082 if (directive_prologue) { | 1088 if (directive_prologue) { |
| 1083 // A shot at a directive. | 1089 // A shot at a directive. |
| 1084 ExpressionStatement* e_stat; | 1090 ExpressionStatement* e_stat; |
| 1085 Literal* literal; | 1091 Literal* literal; |
| 1086 // Still processing directive prologue? | 1092 // Still processing directive prologue? |
| 1087 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1093 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1088 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1094 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1089 literal->value()->IsString()) { | 1095 literal->string() != NULL) { |
| 1090 Handle<String> directive = Handle<String>::cast(literal->value()); | |
| 1091 | |
| 1092 // Check "use strict" directive (ES5 14.1). | 1096 // Check "use strict" directive (ES5 14.1). |
| 1093 if (strict_mode() == SLOPPY && | 1097 if (strict_mode() == SLOPPY && |
| 1094 String::Equals(isolate()->factory()->use_strict_string(), | 1098 literal->string() == symbol_table_->use_strict_string() && |
| 1095 directive) && | 1099 token_loc.end_pos - token_loc.beg_pos == 12) { |
| 1096 token_loc.end_pos - token_loc.beg_pos == | |
| 1097 isolate()->heap()->use_strict_string()->length() + 2) { | |
| 1098 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1100 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 1099 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1101 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 1100 // add this scope in DoParseProgram(), but that requires adaptations | 1102 // add this scope in DoParseProgram(), but that requires adaptations |
| 1101 // all over the code base, so we go with a quick-fix for now. | 1103 // all over the code base, so we go with a quick-fix for now. |
| 1102 // In the same manner, we have to patch the parsing mode. | 1104 // In the same manner, we have to patch the parsing mode. |
| 1103 if (is_eval && !scope_->is_eval_scope()) { | 1105 if (is_eval && !scope_->is_eval_scope()) { |
| 1104 ASSERT(scope_->is_global_scope()); | 1106 ASSERT(scope_->is_global_scope()); |
| 1105 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1107 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 1106 scope->set_start_position(scope_->start_position()); | 1108 scope->set_start_position(scope_->start_position()); |
| 1107 scope->set_end_position(scope_->end_position()); | 1109 scope->set_end_position(scope_->end_position()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1118 } | 1120 } |
| 1119 } | 1121 } |
| 1120 | 1122 |
| 1121 processor->Add(stat, zone()); | 1123 processor->Add(stat, zone()); |
| 1122 } | 1124 } |
| 1123 | 1125 |
| 1124 return 0; | 1126 return 0; |
| 1125 } | 1127 } |
| 1126 | 1128 |
| 1127 | 1129 |
| 1128 Statement* Parser::ParseModuleElement(ZoneStringList* labels, | 1130 Statement* Parser::ParseModuleElement( |
| 1129 bool* ok) { | 1131 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 1130 // (Ecma 262 5th Edition, clause 14): | 1132 // (Ecma 262 5th Edition, clause 14): |
| 1131 // SourceElement: | 1133 // SourceElement: |
| 1132 // Statement | 1134 // Statement |
| 1133 // FunctionDeclaration | 1135 // FunctionDeclaration |
| 1134 // | 1136 // |
| 1135 // In harmony mode we allow additionally the following productions | 1137 // In harmony mode we allow additionally the following productions |
| 1136 // ModuleElement: | 1138 // ModuleElement: |
| 1137 // LetDeclaration | 1139 // LetDeclaration |
| 1138 // ConstDeclaration | 1140 // ConstDeclaration |
| 1139 // ModuleDeclaration | 1141 // ModuleDeclaration |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1152 case Token::EXPORT: | 1154 case Token::EXPORT: |
| 1153 return ParseExportDeclaration(ok); | 1155 return ParseExportDeclaration(ok); |
| 1154 default: { | 1156 default: { |
| 1155 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1157 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 1156 // Handle 'module' as a context-sensitive keyword. | 1158 // Handle 'module' as a context-sensitive keyword. |
| 1157 if (FLAG_harmony_modules && | 1159 if (FLAG_harmony_modules && |
| 1158 peek() == Token::IDENTIFIER && | 1160 peek() == Token::IDENTIFIER && |
| 1159 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1161 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 1160 stmt != NULL) { | 1162 stmt != NULL) { |
| 1161 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1163 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
| 1162 if (estmt != NULL && | 1164 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
| 1163 estmt->expression()->AsVariableProxy() != NULL && | 1165 estmt->expression()->AsVariableProxy()->raw_name() == |
| 1164 String::Equals(isolate()->factory()->module_string(), | 1166 symbol_table_->module_string() && |
| 1165 estmt->expression()->AsVariableProxy()->name()) && | |
| 1166 !scanner()->literal_contains_escapes()) { | 1167 !scanner()->literal_contains_escapes()) { |
| 1167 return ParseModuleDeclaration(NULL, ok); | 1168 return ParseModuleDeclaration(NULL, ok); |
| 1168 } | 1169 } |
| 1169 } | 1170 } |
| 1170 return stmt; | 1171 return stmt; |
| 1171 } | 1172 } |
| 1172 } | 1173 } |
| 1173 } | 1174 } |
| 1174 | 1175 |
| 1175 | 1176 |
| 1176 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 1177 Statement* Parser::ParseModuleDeclaration( |
| 1178 ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
| 1177 // ModuleDeclaration: | 1179 // ModuleDeclaration: |
| 1178 // 'module' Identifier Module | 1180 // 'module' Identifier Module |
| 1179 | 1181 |
| 1180 int pos = peek_position(); | 1182 int pos = peek_position(); |
| 1181 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1183 ParserSymbolTable::Symbol* name = |
| 1184 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1182 | 1185 |
| 1183 #ifdef DEBUG | 1186 #ifdef DEBUG |
| 1184 if (FLAG_print_interface_details) | 1187 if (FLAG_print_interface_details) { |
| 1185 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1188 PrintF("# Module %.*s ", name->literal_bytes.length(), |
| 1189 name->literal_bytes.start()); |
| 1190 } |
| 1186 #endif | 1191 #endif |
| 1187 | 1192 |
| 1188 Module* module = ParseModule(CHECK_OK); | 1193 Module* module = ParseModule(CHECK_OK); |
| 1189 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1194 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 1190 Declaration* declaration = | 1195 Declaration* declaration = |
| 1191 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 1196 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
| 1192 Declare(declaration, true, CHECK_OK); | 1197 Declare(declaration, true, CHECK_OK); |
| 1193 | 1198 |
| 1194 #ifdef DEBUG | 1199 #ifdef DEBUG |
| 1195 if (FLAG_print_interface_details) | 1200 if (FLAG_print_interface_details) { |
| 1196 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1201 PrintF("# Module %.*s ", name->literal_bytes.length(), |
| 1197 | 1202 name->literal_bytes.start()); |
| 1203 } |
| 1198 if (FLAG_print_interfaces) { | 1204 if (FLAG_print_interfaces) { |
| 1199 PrintF("module %s : ", name->ToAsciiArray()); | 1205 PrintF("module %.*s: ", name->literal_bytes.length(), |
| 1206 name->literal_bytes.start()); |
| 1200 module->interface()->Print(); | 1207 module->interface()->Print(); |
| 1201 } | 1208 } |
| 1202 #endif | 1209 #endif |
| 1203 | 1210 |
| 1204 if (names) names->Add(name, zone()); | 1211 if (names) names->Add(name, zone()); |
| 1205 if (module->body() == NULL) | 1212 if (module->body() == NULL) |
| 1206 return factory()->NewEmptyStatement(pos); | 1213 return factory()->NewEmptyStatement(pos); |
| 1207 else | 1214 else |
| 1208 return factory()->NewModuleStatement(proxy, module->body(), pos); | 1215 return factory()->NewModuleStatement(proxy, module->body(), pos); |
| 1209 } | 1216 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 | 1297 |
| 1291 | 1298 |
| 1292 Module* Parser::ParseModulePath(bool* ok) { | 1299 Module* Parser::ParseModulePath(bool* ok) { |
| 1293 // ModulePath: | 1300 // ModulePath: |
| 1294 // Identifier | 1301 // Identifier |
| 1295 // ModulePath '.' Identifier | 1302 // ModulePath '.' Identifier |
| 1296 | 1303 |
| 1297 int pos = peek_position(); | 1304 int pos = peek_position(); |
| 1298 Module* result = ParseModuleVariable(CHECK_OK); | 1305 Module* result = ParseModuleVariable(CHECK_OK); |
| 1299 while (Check(Token::PERIOD)) { | 1306 while (Check(Token::PERIOD)) { |
| 1300 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1307 ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK); |
| 1301 #ifdef DEBUG | 1308 #ifdef DEBUG |
| 1302 if (FLAG_print_interface_details) | 1309 if (FLAG_print_interface_details) { |
| 1303 PrintF("# Path .%s ", name->ToAsciiArray()); | 1310 PrintF("# Path .%.*s ", name->literal_bytes.length(), |
| 1311 name->literal_bytes.start()); |
| 1312 } |
| 1304 #endif | 1313 #endif |
| 1305 Module* member = factory()->NewModulePath(result, name, pos); | 1314 Module* member = |
| 1315 factory()->NewModulePath(result, name, pos); |
| 1306 result->interface()->Add(name, member->interface(), zone(), ok); | 1316 result->interface()->Add(name, member->interface(), zone(), ok); |
| 1307 if (!*ok) { | 1317 if (!*ok) { |
| 1308 #ifdef DEBUG | 1318 #ifdef DEBUG |
| 1309 if (FLAG_print_interfaces) { | 1319 if (FLAG_print_interfaces) { |
| 1310 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1320 PrintF("PATH TYPE ERROR at '%.*s'\n", name->literal_bytes.length(), |
| 1321 name->literal_bytes.start()); |
| 1311 PrintF("result: "); | 1322 PrintF("result: "); |
| 1312 result->interface()->Print(); | 1323 result->interface()->Print(); |
| 1313 PrintF("member: "); | 1324 PrintF("member: "); |
| 1314 member->interface()->Print(); | 1325 member->interface()->Print(); |
| 1315 } | 1326 } |
| 1316 #endif | 1327 #endif |
| 1317 ParserTraits::ReportMessage("invalid_module_path", name); | 1328 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1318 return NULL; | 1329 return NULL; |
| 1319 } | 1330 } |
| 1320 result = member; | 1331 result = member; |
| 1321 } | 1332 } |
| 1322 | 1333 |
| 1323 return result; | 1334 return result; |
| 1324 } | 1335 } |
| 1325 | 1336 |
| 1326 | 1337 |
| 1327 Module* Parser::ParseModuleVariable(bool* ok) { | 1338 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1328 // ModulePath: | 1339 // ModulePath: |
| 1329 // Identifier | 1340 // Identifier |
| 1330 | 1341 |
| 1331 int pos = peek_position(); | 1342 int pos = peek_position(); |
| 1332 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1343 ParserSymbolTable::Symbol* name = |
| 1344 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1333 #ifdef DEBUG | 1345 #ifdef DEBUG |
| 1334 if (FLAG_print_interface_details) | 1346 if (FLAG_print_interface_details) { |
| 1335 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1347 PrintF("# Module variable %.*s ", name->literal_bytes.length(), |
| 1348 name->literal_bytes.start()); |
| 1349 } |
| 1336 #endif | 1350 #endif |
| 1337 VariableProxy* proxy = scope_->NewUnresolved( | 1351 VariableProxy* proxy = scope_->NewUnresolved( |
| 1338 factory(), name, Interface::NewModule(zone()), | 1352 factory(), name, Interface::NewModule(zone()), |
| 1339 scanner()->location().beg_pos); | 1353 scanner()->location().beg_pos); |
| 1340 | 1354 |
| 1341 return factory()->NewModuleVariable(proxy, pos); | 1355 return factory()->NewModuleVariable(proxy, pos); |
| 1342 } | 1356 } |
| 1343 | 1357 |
| 1344 | 1358 |
| 1345 Module* Parser::ParseModuleUrl(bool* ok) { | 1359 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1346 // Module: | 1360 // Module: |
| 1347 // String | 1361 // String |
| 1348 | 1362 |
| 1349 int pos = peek_position(); | 1363 int pos = peek_position(); |
| 1350 Expect(Token::STRING, CHECK_OK); | 1364 Expect(Token::STRING, CHECK_OK); |
| 1351 Handle<String> symbol = GetSymbol(); | 1365 ParserSymbolTable::Symbol* symbol = GetSymbol(scanner()); |
| 1352 | 1366 |
| 1353 // TODO(ES6): Request JS resource from environment... | 1367 // TODO(ES6): Request JS resource from environment... |
| 1354 | 1368 |
| 1355 #ifdef DEBUG | 1369 #ifdef DEBUG |
| 1356 if (FLAG_print_interface_details) PrintF("# Url "); | 1370 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1357 #endif | 1371 #endif |
| 1358 | 1372 |
| 1359 // Create an empty literal as long as the feature isn't finished. | 1373 // Create an empty literal as long as the feature isn't finished. |
| 1360 USE(symbol); | 1374 USE(symbol); |
| 1361 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1375 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1385 | 1399 |
| 1386 | 1400 |
| 1387 Block* Parser::ParseImportDeclaration(bool* ok) { | 1401 Block* Parser::ParseImportDeclaration(bool* ok) { |
| 1388 // ImportDeclaration: | 1402 // ImportDeclaration: |
| 1389 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1403 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1390 // | 1404 // |
| 1391 // TODO(ES6): implement destructuring ImportSpecifiers | 1405 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1392 | 1406 |
| 1393 int pos = peek_position(); | 1407 int pos = peek_position(); |
| 1394 Expect(Token::IMPORT, CHECK_OK); | 1408 Expect(Token::IMPORT, CHECK_OK); |
| 1395 ZoneStringList names(1, zone()); | 1409 ZoneList<ParserSymbolTable::Symbol*> names(1, zone()); |
| 1396 | 1410 |
| 1397 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1411 ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK); |
| 1398 names.Add(name, zone()); | 1412 names.Add(name, zone()); |
| 1399 while (peek() == Token::COMMA) { | 1413 while (peek() == Token::COMMA) { |
| 1400 Consume(Token::COMMA); | 1414 Consume(Token::COMMA); |
| 1401 name = ParseIdentifierName(CHECK_OK); | 1415 name = ParseIdentifierName(CHECK_OK); |
| 1402 names.Add(name, zone()); | 1416 names.Add(name, zone()); |
| 1403 } | 1417 } |
| 1404 | 1418 |
| 1405 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1419 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1406 Module* module = ParseModuleSpecifier(CHECK_OK); | 1420 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1407 ExpectSemicolon(CHECK_OK); | 1421 ExpectSemicolon(CHECK_OK); |
| 1408 | 1422 |
| 1409 // Generate a separate declaration for each identifier. | 1423 // Generate a separate declaration for each identifier. |
| 1410 // TODO(ES6): once we implement destructuring, make that one declaration. | 1424 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1411 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1425 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 1412 for (int i = 0; i < names.length(); ++i) { | 1426 for (int i = 0; i < names.length(); ++i) { |
| 1413 #ifdef DEBUG | 1427 #ifdef DEBUG |
| 1414 if (FLAG_print_interface_details) | 1428 if (FLAG_print_interface_details) { |
| 1415 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1429 PrintF("# Import %.*s ", name->literal_bytes.length(), |
| 1430 name->literal_bytes.start()); |
| 1431 } |
| 1416 #endif | 1432 #endif |
| 1417 Interface* interface = Interface::NewUnknown(zone()); | 1433 Interface* interface = Interface::NewUnknown(zone()); |
| 1418 module->interface()->Add(names[i], interface, zone(), ok); | 1434 module->interface()->Add(names[i], interface, zone(), ok); |
| 1419 if (!*ok) { | 1435 if (!*ok) { |
| 1420 #ifdef DEBUG | 1436 #ifdef DEBUG |
| 1421 if (FLAG_print_interfaces) { | 1437 if (FLAG_print_interfaces) { |
| 1422 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1438 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->literal_bytes.length(), |
| 1439 name->literal_bytes.start()); |
| 1423 PrintF("module: "); | 1440 PrintF("module: "); |
| 1424 module->interface()->Print(); | 1441 module->interface()->Print(); |
| 1425 } | 1442 } |
| 1426 #endif | 1443 #endif |
| 1427 ParserTraits::ReportMessage("invalid_module_path", name); | 1444 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1428 return NULL; | 1445 return NULL; |
| 1429 } | 1446 } |
| 1430 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1447 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1431 Declaration* declaration = | 1448 Declaration* declaration = |
| 1432 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1449 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1443 // 'export' VariableDeclaration | 1460 // 'export' VariableDeclaration |
| 1444 // 'export' FunctionDeclaration | 1461 // 'export' FunctionDeclaration |
| 1445 // 'export' GeneratorDeclaration | 1462 // 'export' GeneratorDeclaration |
| 1446 // 'export' ModuleDeclaration | 1463 // 'export' ModuleDeclaration |
| 1447 // | 1464 // |
| 1448 // TODO(ES6): implement structuring ExportSpecifiers | 1465 // TODO(ES6): implement structuring ExportSpecifiers |
| 1449 | 1466 |
| 1450 Expect(Token::EXPORT, CHECK_OK); | 1467 Expect(Token::EXPORT, CHECK_OK); |
| 1451 | 1468 |
| 1452 Statement* result = NULL; | 1469 Statement* result = NULL; |
| 1453 ZoneStringList names(1, zone()); | 1470 ZoneList<ParserSymbolTable::Symbol*> names(1, zone()); |
| 1454 switch (peek()) { | 1471 switch (peek()) { |
| 1455 case Token::IDENTIFIER: { | 1472 case Token::IDENTIFIER: { |
| 1456 int pos = position(); | 1473 int pos = position(); |
| 1457 Handle<String> name = | 1474 ParserSymbolTable::Symbol* name = |
| 1458 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1475 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1459 // Handle 'module' as a context-sensitive keyword. | 1476 // Handle 'module' as a context-sensitive keyword. |
| 1460 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1477 if (name != symbol_table_->module_string()) { |
| 1461 names.Add(name, zone()); | 1478 names.Add(name, zone()); |
| 1462 while (peek() == Token::COMMA) { | 1479 while (peek() == Token::COMMA) { |
| 1463 Consume(Token::COMMA); | 1480 Consume(Token::COMMA); |
| 1464 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1481 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1465 names.Add(name, zone()); | 1482 names.Add(name, zone()); |
| 1466 } | 1483 } |
| 1467 ExpectSemicolon(CHECK_OK); | 1484 ExpectSemicolon(CHECK_OK); |
| 1468 result = factory()->NewEmptyStatement(pos); | 1485 result = factory()->NewEmptyStatement(pos); |
| 1469 } else { | 1486 } else { |
| 1470 result = ParseModuleDeclaration(&names, CHECK_OK); | 1487 result = ParseModuleDeclaration(&names, CHECK_OK); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1485 default: | 1502 default: |
| 1486 *ok = false; | 1503 *ok = false; |
| 1487 ReportUnexpectedToken(scanner()->current_token()); | 1504 ReportUnexpectedToken(scanner()->current_token()); |
| 1488 return NULL; | 1505 return NULL; |
| 1489 } | 1506 } |
| 1490 | 1507 |
| 1491 // Extract declared names into export declarations and interface. | 1508 // Extract declared names into export declarations and interface. |
| 1492 Interface* interface = scope_->interface(); | 1509 Interface* interface = scope_->interface(); |
| 1493 for (int i = 0; i < names.length(); ++i) { | 1510 for (int i = 0; i < names.length(); ++i) { |
| 1494 #ifdef DEBUG | 1511 #ifdef DEBUG |
| 1495 if (FLAG_print_interface_details) | 1512 if (FLAG_print_interface_details) { |
| 1496 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1513 PrintF("# Export %.*s ", names[i]->literal_bytes.length(), |
| 1514 names[i]->literal_bytes.start()); |
| 1515 } |
| 1497 #endif | 1516 #endif |
| 1498 Interface* inner = Interface::NewUnknown(zone()); | 1517 Interface* inner = Interface::NewUnknown(zone()); |
| 1499 interface->Add(names[i], inner, zone(), CHECK_OK); | 1518 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1500 if (!*ok) | 1519 if (!*ok) |
| 1501 return NULL; | 1520 return NULL; |
| 1502 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1521 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1503 USE(proxy); | 1522 USE(proxy); |
| 1504 // TODO(rossberg): Rethink whether we actually need to store export | 1523 // TODO(rossberg): Rethink whether we actually need to store export |
| 1505 // declarations (for compilation?). | 1524 // declarations (for compilation?). |
| 1506 // ExportDeclaration* declaration = | 1525 // ExportDeclaration* declaration = |
| 1507 // factory()->NewExportDeclaration(proxy, scope_, position); | 1526 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1508 // scope_->AddDeclaration(declaration); | 1527 // scope_->AddDeclaration(declaration); |
| 1509 } | 1528 } |
| 1510 | 1529 |
| 1511 ASSERT(result != NULL); | 1530 ASSERT(result != NULL); |
| 1512 return result; | 1531 return result; |
| 1513 } | 1532 } |
| 1514 | 1533 |
| 1515 | 1534 |
| 1516 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1535 Statement* Parser::ParseBlockElement( |
| 1517 bool* ok) { | 1536 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 1518 // (Ecma 262 5th Edition, clause 14): | 1537 // (Ecma 262 5th Edition, clause 14): |
| 1519 // SourceElement: | 1538 // SourceElement: |
| 1520 // Statement | 1539 // Statement |
| 1521 // FunctionDeclaration | 1540 // FunctionDeclaration |
| 1522 // | 1541 // |
| 1523 // In harmony mode we allow additionally the following productions | 1542 // In harmony mode we allow additionally the following productions |
| 1524 // BlockElement (aka SourceElement): | 1543 // BlockElement (aka SourceElement): |
| 1525 // LetDeclaration | 1544 // LetDeclaration |
| 1526 // ConstDeclaration | 1545 // ConstDeclaration |
| 1527 // GeneratorDeclaration | 1546 // GeneratorDeclaration |
| 1528 | 1547 |
| 1529 switch (peek()) { | 1548 switch (peek()) { |
| 1530 case Token::FUNCTION: | 1549 case Token::FUNCTION: |
| 1531 return ParseFunctionDeclaration(NULL, ok); | 1550 return ParseFunctionDeclaration(NULL, ok); |
| 1532 case Token::LET: | 1551 case Token::LET: |
| 1533 case Token::CONST: | 1552 case Token::CONST: |
| 1534 return ParseVariableStatement(kModuleElement, NULL, ok); | 1553 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1535 default: | 1554 default: |
| 1536 return ParseStatement(labels, ok); | 1555 return ParseStatement(labels, ok); |
| 1537 } | 1556 } |
| 1538 } | 1557 } |
| 1539 | 1558 |
| 1540 | 1559 |
| 1541 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1560 Statement* Parser::ParseStatement(ZoneList<ParserSymbolTable::Symbol*>* labels, |
| 1561 bool* ok) { |
| 1542 // Statement :: | 1562 // Statement :: |
| 1543 // Block | 1563 // Block |
| 1544 // VariableStatement | 1564 // VariableStatement |
| 1545 // EmptyStatement | 1565 // EmptyStatement |
| 1546 // ExpressionStatement | 1566 // ExpressionStatement |
| 1547 // IfStatement | 1567 // IfStatement |
| 1548 // IterationStatement | 1568 // IterationStatement |
| 1549 // ContinueStatement | 1569 // ContinueStatement |
| 1550 // BreakStatement | 1570 // BreakStatement |
| 1551 // ReturnStatement | 1571 // ReturnStatement |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 // SourceElement: | 1645 // SourceElement: |
| 1626 // Statement | 1646 // Statement |
| 1627 // FunctionDeclaration | 1647 // FunctionDeclaration |
| 1628 // Common language extension is to allow function declaration in place | 1648 // Common language extension is to allow function declaration in place |
| 1629 // of any statement. This language extension is disabled in strict mode. | 1649 // of any statement. This language extension is disabled in strict mode. |
| 1630 // | 1650 // |
| 1631 // In Harmony mode, this case also handles the extension: | 1651 // In Harmony mode, this case also handles the extension: |
| 1632 // Statement: | 1652 // Statement: |
| 1633 // GeneratorDeclaration | 1653 // GeneratorDeclaration |
| 1634 if (strict_mode() == STRICT) { | 1654 if (strict_mode() == STRICT) { |
| 1635 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1655 ParserTraits::ReportMessageAt(scanner()->peek_location(), |
| 1656 "strict_function"); |
| 1636 *ok = false; | 1657 *ok = false; |
| 1637 return NULL; | 1658 return NULL; |
| 1638 } | 1659 } |
| 1639 return ParseFunctionDeclaration(NULL, ok); | 1660 return ParseFunctionDeclaration(NULL, ok); |
| 1640 } | 1661 } |
| 1641 | 1662 |
| 1642 case Token::DEBUGGER: | 1663 case Token::DEBUGGER: |
| 1643 return ParseDebuggerStatement(ok); | 1664 return ParseDebuggerStatement(ok); |
| 1644 | 1665 |
| 1645 default: | 1666 default: |
| 1646 return ParseExpressionOrLabelledStatement(labels, ok); | 1667 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1647 } | 1668 } |
| 1648 } | 1669 } |
| 1649 | 1670 |
| 1650 | 1671 |
| 1672 template<typename SymbolType> |
| 1651 VariableProxy* Parser::NewUnresolved( | 1673 VariableProxy* Parser::NewUnresolved( |
| 1652 Handle<String> name, VariableMode mode, Interface* interface) { | 1674 SymbolType name, VariableMode mode, Interface* interface) { |
| 1653 // If we are inside a function, a declaration of a var/const variable is a | 1675 // If we are inside a function, a declaration of a var/const variable is a |
| 1654 // truly local variable, and the scope of the variable is always the function | 1676 // truly local variable, and the scope of the variable is always the function |
| 1655 // scope. | 1677 // scope. |
| 1656 // Let/const variables in harmony mode are always added to the immediately | 1678 // Let/const variables in harmony mode are always added to the immediately |
| 1657 // enclosing scope. | 1679 // enclosing scope. |
| 1658 return DeclarationScope(mode)->NewUnresolved( | 1680 return DeclarationScope(mode)->NewUnresolved( |
| 1659 factory(), name, interface, position()); | 1681 factory(), name, interface, position()); |
| 1660 } | 1682 } |
| 1661 | 1683 |
| 1662 | 1684 |
| 1663 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1685 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1664 VariableProxy* proxy = declaration->proxy(); | 1686 VariableProxy* proxy = declaration->proxy(); |
| 1665 Handle<String> name = proxy->name(); | 1687 ASSERT(proxy->raw_name() != NULL); |
| 1688 ParserSymbolTable::Symbol* name = proxy->raw_name(); |
| 1666 VariableMode mode = declaration->mode(); | 1689 VariableMode mode = declaration->mode(); |
| 1667 Scope* declaration_scope = DeclarationScope(mode); | 1690 Scope* declaration_scope = DeclarationScope(mode); |
| 1668 Variable* var = NULL; | 1691 Variable* var = NULL; |
| 1669 | 1692 |
| 1670 // If a suitable scope exists, then we can statically declare this | 1693 // If a suitable scope exists, then we can statically declare this |
| 1671 // variable and also set its mode. In any case, a Declaration node | 1694 // variable and also set its mode. In any case, a Declaration node |
| 1672 // will be added to the scope so that the declaration can be added | 1695 // will be added to the scope so that the declaration can be added |
| 1673 // to the corresponding activation frame at runtime if necessary. | 1696 // to the corresponding activation frame at runtime if necessary. |
| 1674 // For instance declarations inside an eval scope need to be added | 1697 // For instance declarations inside an eval scope need to be added |
| 1675 // to the calling function context. | 1698 // to the calling function context. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1783 // with a context slot index and a context chain length for this | 1806 // with a context slot index and a context chain length for this |
| 1784 // initialization code. Thus, inside the 'with' statement, we need | 1807 // initialization code. Thus, inside the 'with' statement, we need |
| 1785 // both access to the static and the dynamic context chain; the | 1808 // both access to the static and the dynamic context chain; the |
| 1786 // runtime needs to provide both. | 1809 // runtime needs to provide both. |
| 1787 if (resolve && var != NULL) { | 1810 if (resolve && var != NULL) { |
| 1788 proxy->BindTo(var); | 1811 proxy->BindTo(var); |
| 1789 | 1812 |
| 1790 if (FLAG_harmony_modules) { | 1813 if (FLAG_harmony_modules) { |
| 1791 bool ok; | 1814 bool ok; |
| 1792 #ifdef DEBUG | 1815 #ifdef DEBUG |
| 1793 if (FLAG_print_interface_details) | 1816 if (FLAG_print_interface_details) { |
| 1794 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); | 1817 if (!var->name().is_null()) { |
| 1818 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); |
| 1819 } else { |
| 1820 ASSERT(var->raw_name() != NULL); |
| 1821 PrintF("# Declare %.*s ", var->raw_name()->literal_bytes.length(), |
| 1822 var->raw_name()->literal_bytes.start()); |
| 1823 } |
| 1824 } |
| 1795 #endif | 1825 #endif |
| 1796 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1826 proxy->interface()->Unify(var->interface(), zone(), &ok); |
| 1797 if (!ok) { | 1827 if (!ok) { |
| 1798 #ifdef DEBUG | 1828 #ifdef DEBUG |
| 1799 if (FLAG_print_interfaces) { | 1829 if (FLAG_print_interfaces) { |
| 1800 PrintF("DECLARE TYPE ERROR\n"); | 1830 PrintF("DECLARE TYPE ERROR\n"); |
| 1801 PrintF("proxy: "); | 1831 PrintF("proxy: "); |
| 1802 proxy->interface()->Print(); | 1832 proxy->interface()->Print(); |
| 1803 PrintF("var: "); | 1833 PrintF("var: "); |
| 1804 var->interface()->Print(); | 1834 var->interface()->Print(); |
| 1805 } | 1835 } |
| 1806 #endif | 1836 #endif |
| 1807 ParserTraits::ReportMessage("module_type_error", name); | 1837 ParserTraits::ReportMessage("module_type_error", name); |
| 1808 } | 1838 } |
| 1809 } | 1839 } |
| 1810 } | 1840 } |
| 1811 } | 1841 } |
| 1812 | 1842 |
| 1813 | 1843 |
| 1814 // Language extension which is only enabled for source files loaded | 1844 // Language extension which is only enabled for source files loaded |
| 1815 // through the API's extension mechanism. A native function | 1845 // through the API's extension mechanism. A native function |
| 1816 // declaration is resolved by looking up the function through a | 1846 // declaration is resolved by looking up the function through a |
| 1817 // callback provided by the extension. | 1847 // callback provided by the extension. |
| 1818 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1848 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1819 int pos = peek_position(); | 1849 int pos = peek_position(); |
| 1820 Expect(Token::FUNCTION, CHECK_OK); | 1850 Expect(Token::FUNCTION, CHECK_OK); |
| 1821 // Allow "eval" or "arguments" for backward compatibility. | 1851 // Allow "eval" or "arguments" for backward compatibility. |
| 1822 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1852 ParserSymbolTable::Symbol* name = |
| 1853 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1823 Expect(Token::LPAREN, CHECK_OK); | 1854 Expect(Token::LPAREN, CHECK_OK); |
| 1824 bool done = (peek() == Token::RPAREN); | 1855 bool done = (peek() == Token::RPAREN); |
| 1825 while (!done) { | 1856 while (!done) { |
| 1826 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1857 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1827 done = (peek() == Token::RPAREN); | 1858 done = (peek() == Token::RPAREN); |
| 1828 if (!done) { | 1859 if (!done) { |
| 1829 Expect(Token::COMMA, CHECK_OK); | 1860 Expect(Token::COMMA, CHECK_OK); |
| 1830 } | 1861 } |
| 1831 } | 1862 } |
| 1832 Expect(Token::RPAREN, CHECK_OK); | 1863 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1847 Declare(declaration, true, CHECK_OK); | 1878 Declare(declaration, true, CHECK_OK); |
| 1848 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1879 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1849 name, extension_, RelocInfo::kNoPosition); | 1880 name, extension_, RelocInfo::kNoPosition); |
| 1850 return factory()->NewExpressionStatement( | 1881 return factory()->NewExpressionStatement( |
| 1851 factory()->NewAssignment( | 1882 factory()->NewAssignment( |
| 1852 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1883 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1853 pos); | 1884 pos); |
| 1854 } | 1885 } |
| 1855 | 1886 |
| 1856 | 1887 |
| 1857 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1888 Statement* Parser::ParseFunctionDeclaration( |
| 1889 ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
| 1858 // FunctionDeclaration :: | 1890 // FunctionDeclaration :: |
| 1859 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1891 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1860 // GeneratorDeclaration :: | 1892 // GeneratorDeclaration :: |
| 1861 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1893 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1862 // '{' FunctionBody '}' | 1894 // '{' FunctionBody '}' |
| 1863 Expect(Token::FUNCTION, CHECK_OK); | 1895 Expect(Token::FUNCTION, CHECK_OK); |
| 1864 int pos = position(); | 1896 int pos = position(); |
| 1865 bool is_generator = allow_generators() && Check(Token::MUL); | 1897 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1866 bool is_strict_reserved = false; | 1898 bool is_strict_reserved = false; |
| 1867 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1899 ParserSymbolTable::Symbol* name = ParseIdentifierOrStrictReservedWord( |
| 1868 &is_strict_reserved, CHECK_OK); | 1900 &is_strict_reserved, CHECK_OK); |
| 1869 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1901 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1870 scanner()->location(), | 1902 scanner()->location(), |
| 1871 is_strict_reserved, | 1903 is_strict_reserved, |
| 1872 is_generator, | 1904 is_generator, |
| 1873 pos, | 1905 pos, |
| 1874 FunctionLiteral::DECLARATION, | 1906 FunctionLiteral::DECLARATION, |
| 1875 CHECK_OK); | 1907 CHECK_OK); |
| 1876 // Even if we're not at the top-level of the global or a function | 1908 // Even if we're not at the top-level of the global or a function |
| 1877 // scope, we treat it as such and introduce the function with its | 1909 // scope, we treat it as such and introduce the function with its |
| 1878 // initial value upon entering the corresponding scope. | 1910 // initial value upon entering the corresponding scope. |
| 1879 // In extended mode, a function behaves as a lexical binding, except in the | 1911 // In extended mode, a function behaves as a lexical binding, except in the |
| 1880 // global scope. | 1912 // global scope. |
| 1881 VariableMode mode = | 1913 VariableMode mode = |
| 1882 allow_harmony_scoping() && | 1914 allow_harmony_scoping() && |
| 1883 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1915 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| 1884 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1916 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1885 Declaration* declaration = | 1917 Declaration* declaration = |
| 1886 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1918 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1887 Declare(declaration, true, CHECK_OK); | 1919 Declare(declaration, true, CHECK_OK); |
| 1888 if (names) names->Add(name, zone()); | 1920 if (names) names->Add(name, zone()); |
| 1889 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1921 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1890 } | 1922 } |
| 1891 | 1923 |
| 1892 | 1924 |
| 1893 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1925 Block* Parser::ParseBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok
) { |
| 1894 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1926 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1895 return ParseScopedBlock(labels, ok); | 1927 return ParseScopedBlock(labels, ok); |
| 1896 } | 1928 } |
| 1897 | 1929 |
| 1898 // Block :: | 1930 // Block :: |
| 1899 // '{' Statement* '}' | 1931 // '{' Statement* '}' |
| 1900 | 1932 |
| 1901 // Note that a Block does not introduce a new execution scope! | 1933 // Note that a Block does not introduce a new execution scope! |
| 1902 // (ECMA-262, 3rd, 12.2) | 1934 // (ECMA-262, 3rd, 12.2) |
| 1903 // | 1935 // |
| 1904 // Construct block expecting 16 statements. | 1936 // Construct block expecting 16 statements. |
| 1905 Block* result = | 1937 Block* result = |
| 1906 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1938 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1907 Target target(&this->target_stack_, result); | 1939 Target target(&this->target_stack_, result); |
| 1908 Expect(Token::LBRACE, CHECK_OK); | 1940 Expect(Token::LBRACE, CHECK_OK); |
| 1909 while (peek() != Token::RBRACE) { | 1941 while (peek() != Token::RBRACE) { |
| 1910 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1942 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1911 if (stat && !stat->IsEmpty()) { | 1943 if (stat && !stat->IsEmpty()) { |
| 1912 result->AddStatement(stat, zone()); | 1944 result->AddStatement(stat, zone()); |
| 1913 } | 1945 } |
| 1914 } | 1946 } |
| 1915 Expect(Token::RBRACE, CHECK_OK); | 1947 Expect(Token::RBRACE, CHECK_OK); |
| 1916 return result; | 1948 return result; |
| 1917 } | 1949 } |
| 1918 | 1950 |
| 1919 | 1951 |
| 1920 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1952 Block* Parser::ParseScopedBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bo
ol* ok) { |
| 1921 // The harmony mode uses block elements instead of statements. | 1953 // The harmony mode uses block elements instead of statements. |
| 1922 // | 1954 // |
| 1923 // Block :: | 1955 // Block :: |
| 1924 // '{' BlockElement* '}' | 1956 // '{' BlockElement* '}' |
| 1925 | 1957 |
| 1926 // Construct block expecting 16 statements. | 1958 // Construct block expecting 16 statements. |
| 1927 Block* body = | 1959 Block* body = |
| 1928 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1960 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1929 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1961 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 1930 | 1962 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1944 } | 1976 } |
| 1945 } | 1977 } |
| 1946 Expect(Token::RBRACE, CHECK_OK); | 1978 Expect(Token::RBRACE, CHECK_OK); |
| 1947 block_scope->set_end_position(scanner()->location().end_pos); | 1979 block_scope->set_end_position(scanner()->location().end_pos); |
| 1948 block_scope = block_scope->FinalizeBlockScope(); | 1980 block_scope = block_scope->FinalizeBlockScope(); |
| 1949 body->set_scope(block_scope); | 1981 body->set_scope(block_scope); |
| 1950 return body; | 1982 return body; |
| 1951 } | 1983 } |
| 1952 | 1984 |
| 1953 | 1985 |
| 1954 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1986 Block* Parser::ParseVariableStatement( |
| 1955 ZoneStringList* names, | 1987 VariableDeclarationContext var_context, |
| 1956 bool* ok) { | 1988 ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
| 1957 // VariableStatement :: | 1989 // VariableStatement :: |
| 1958 // VariableDeclarations ';' | 1990 // VariableDeclarations ';' |
| 1959 | 1991 |
| 1960 Handle<String> ignore; | 1992 ParserSymbolTable::Symbol* ignore; |
| 1961 Block* result = | 1993 Block* result = |
| 1962 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1994 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1963 ExpectSemicolon(CHECK_OK); | 1995 ExpectSemicolon(CHECK_OK); |
| 1964 return result; | 1996 return result; |
| 1965 } | 1997 } |
| 1966 | 1998 |
| 1967 | 1999 |
| 1968 // If the variable declaration declares exactly one non-const | 2000 // If the variable declaration declares exactly one non-const |
| 1969 // variable, then *out is set to that variable. In all other cases, | 2001 // variable, then *out is set to that variable. In all other cases, |
| 1970 // *out is untouched; in particular, it is the caller's responsibility | 2002 // *out is untouched; in particular, it is the caller's responsibility |
| 1971 // to initialize it properly. This mechanism is used for the parsing | 2003 // to initialize it properly. This mechanism is used for the parsing |
| 1972 // of 'for-in' loops. | 2004 // of 'for-in' loops. |
| 1973 Block* Parser::ParseVariableDeclarations( | 2005 Block* Parser::ParseVariableDeclarations( |
| 1974 VariableDeclarationContext var_context, | 2006 VariableDeclarationContext var_context, |
| 1975 VariableDeclarationProperties* decl_props, | 2007 VariableDeclarationProperties* decl_props, |
| 1976 ZoneStringList* names, | 2008 ZoneList<ParserSymbolTable::Symbol*>* names, |
| 1977 Handle<String>* out, | 2009 ParserSymbolTable::Symbol** out, |
| 1978 bool* ok) { | 2010 bool* ok) { |
| 1979 // VariableDeclarations :: | 2011 // VariableDeclarations :: |
| 1980 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 2012 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1981 // | 2013 // |
| 1982 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 2014 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1983 // | 2015 // |
| 1984 // ConstDeclaration :: | 2016 // ConstDeclaration :: |
| 1985 // const ConstBinding (',' ConstBinding)* ';' | 2017 // const ConstBinding (',' ConstBinding)* ';' |
| 1986 // ConstBinding :: | 2018 // ConstBinding :: |
| 1987 // Identifier '=' AssignmentExpression | 2019 // Identifier '=' AssignmentExpression |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2075 // | 2107 // |
| 2076 // We mark the block as initializer block because we don't want the | 2108 // We mark the block as initializer block because we don't want the |
| 2077 // rewriter to add a '.result' assignment to such a block (to get compliant | 2109 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 2078 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2110 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 2079 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2111 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 2080 // is inside an initializer block, it is ignored. | 2112 // is inside an initializer block, it is ignored. |
| 2081 // | 2113 // |
| 2082 // Create new block with one expected declaration. | 2114 // Create new block with one expected declaration. |
| 2083 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2115 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 2084 int nvars = 0; // the number of variables declared | 2116 int nvars = 0; // the number of variables declared |
| 2085 Handle<String> name; | 2117 ParserSymbolTable::Symbol* name = NULL; |
| 2086 do { | 2118 do { |
| 2087 if (fni_ != NULL) fni_->Enter(); | 2119 if (fni_ != NULL) fni_->Enter(); |
| 2088 | 2120 |
| 2089 // Parse variable name. | 2121 // Parse variable name. |
| 2090 if (nvars > 0) Consume(Token::COMMA); | 2122 if (nvars > 0) Consume(Token::COMMA); |
| 2091 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2123 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2092 if (fni_ != NULL) fni_->PushVariableName(name); | 2124 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2093 | 2125 |
| 2094 // Declare variable. | 2126 // Declare variable. |
| 2095 // Note that we *always* must treat the initial value via a separate init | 2127 // Note that we *always* must treat the initial value via a separate init |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2107 // pre-resolve the proxy because it resides in the same scope as the | 2139 // pre-resolve the proxy because it resides in the same scope as the |
| 2108 // declaration. | 2140 // declaration. |
| 2109 Interface* interface = | 2141 Interface* interface = |
| 2110 is_const ? Interface::NewConst() : Interface::NewValue(); | 2142 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2111 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 2143 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 2112 Declaration* declaration = | 2144 Declaration* declaration = |
| 2113 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2145 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 2114 Declare(declaration, mode != VAR, CHECK_OK); | 2146 Declare(declaration, mode != VAR, CHECK_OK); |
| 2115 nvars++; | 2147 nvars++; |
| 2116 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 2148 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 2117 ReportMessageAt(scanner()->location(), "too_many_variables"); | 2149 ReportMessage("too_many_variables"); |
| 2118 *ok = false; | 2150 *ok = false; |
| 2119 return NULL; | 2151 return NULL; |
| 2120 } | 2152 } |
| 2121 if (names) names->Add(name, zone()); | 2153 if (names) names->Add(name, zone()); |
| 2122 | 2154 |
| 2123 // Parse initialization expression if present and/or needed. A | 2155 // Parse initialization expression if present and/or needed. A |
| 2124 // declaration of the form: | 2156 // declaration of the form: |
| 2125 // | 2157 // |
| 2126 // var v = x; | 2158 // var v = x; |
| 2127 // | 2159 // |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 | 2238 |
| 2207 if (is_const) { | 2239 if (is_const) { |
| 2208 arguments->Add(value, zone()); | 2240 arguments->Add(value, zone()); |
| 2209 value = NULL; // zap the value to avoid the unnecessary assignment | 2241 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2210 | 2242 |
| 2211 // Construct the call to Runtime_InitializeConstGlobal | 2243 // Construct the call to Runtime_InitializeConstGlobal |
| 2212 // and add it to the initialization statement block. | 2244 // and add it to the initialization statement block. |
| 2213 // Note that the function does different things depending on | 2245 // Note that the function does different things depending on |
| 2214 // the number of arguments (1 or 2). | 2246 // the number of arguments (1 or 2). |
| 2215 initialize = factory()->NewCallRuntime( | 2247 initialize = factory()->NewCallRuntime( |
| 2216 isolate()->factory()->InitializeConstGlobal_string(), | 2248 symbol_table_->initialize_const_global_string(), |
| 2217 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), | 2249 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
| 2218 arguments, pos); | 2250 arguments, pos); |
| 2219 } else { | 2251 } else { |
| 2220 // Add strict mode. | 2252 // Add strict mode. |
| 2221 // We may want to pass singleton to avoid Literal allocations. | 2253 // We may want to pass singleton to avoid Literal allocations. |
| 2222 StrictMode strict_mode = initialization_scope->strict_mode(); | 2254 StrictMode strict_mode = initialization_scope->strict_mode(); |
| 2223 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2255 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
| 2224 | 2256 |
| 2225 // Be careful not to assign a value to the global variable if | 2257 // Be careful not to assign a value to the global variable if |
| 2226 // we're in a with. The initialization value should not | 2258 // we're in a with. The initialization value should not |
| 2227 // necessarily be stored in the global object in that case, | 2259 // necessarily be stored in the global object in that case, |
| 2228 // which is why we need to generate a separate assignment node. | 2260 // which is why we need to generate a separate assignment node. |
| 2229 if (value != NULL && !inside_with()) { | 2261 if (value != NULL && !inside_with()) { |
| 2230 arguments->Add(value, zone()); | 2262 arguments->Add(value, zone()); |
| 2231 value = NULL; // zap the value to avoid the unnecessary assignment | 2263 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2232 } | 2264 } |
| 2233 | 2265 |
| 2234 // Construct the call to Runtime_InitializeVarGlobal | 2266 // Construct the call to Runtime_InitializeVarGlobal |
| 2235 // and add it to the initialization statement block. | 2267 // and add it to the initialization statement block. |
| 2236 // Note that the function does different things depending on | 2268 // Note that the function does different things depending on |
| 2237 // the number of arguments (2 or 3). | 2269 // the number of arguments (2 or 3). |
| 2238 initialize = factory()->NewCallRuntime( | 2270 initialize = factory()->NewCallRuntime( |
| 2239 isolate()->factory()->InitializeVarGlobal_string(), | 2271 symbol_table_->initialize_var_global_string(), |
| 2240 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2272 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 2241 arguments, pos); | 2273 arguments, pos); |
| 2242 } | 2274 } |
| 2243 | 2275 |
| 2244 block->AddStatement( | 2276 block->AddStatement( |
| 2245 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 2277 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
| 2246 zone()); | 2278 zone()); |
| 2247 } else if (needs_init) { | 2279 } else if (needs_init) { |
| 2248 // Constant initializations always assign to the declared constant which | 2280 // Constant initializations always assign to the declared constant which |
| 2249 // is always at the function scope level. This is only relevant for | 2281 // is always at the function scope level. This is only relevant for |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 // If there was a single non-const declaration, return it in the output | 2317 // If there was a single non-const declaration, return it in the output |
| 2286 // parameter for possible use by for/in. | 2318 // parameter for possible use by for/in. |
| 2287 if (nvars == 1 && !is_const) { | 2319 if (nvars == 1 && !is_const) { |
| 2288 *out = name; | 2320 *out = name; |
| 2289 } | 2321 } |
| 2290 | 2322 |
| 2291 return block; | 2323 return block; |
| 2292 } | 2324 } |
| 2293 | 2325 |
| 2294 | 2326 |
| 2295 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { | 2327 static bool ContainsLabel(ZoneList<ParserSymbolTable::Symbol*>* labels, |
| 2296 ASSERT(!label.is_null()); | 2328 ParserSymbolTable::Symbol* label) { |
| 2329 ASSERT(label != NULL); |
| 2297 if (labels != NULL) | 2330 if (labels != NULL) |
| 2298 for (int i = labels->length(); i-- > 0; ) | 2331 for (int i = labels->length(); i-- > 0; ) |
| 2299 if (labels->at(i).is_identical_to(label)) | 2332 if (labels->at(i) == label) |
| 2300 return true; | 2333 return true; |
| 2301 | 2334 |
| 2302 return false; | 2335 return false; |
| 2303 } | 2336 } |
| 2304 | 2337 |
| 2305 | 2338 |
| 2306 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2339 Statement* Parser::ParseExpressionOrLabelledStatement( |
| 2307 bool* ok) { | 2340 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2308 // ExpressionStatement | LabelledStatement :: | 2341 // ExpressionStatement | LabelledStatement :: |
| 2309 // Expression ';' | 2342 // Expression ';' |
| 2310 // Identifier ':' Statement | 2343 // Identifier ':' Statement |
| 2311 int pos = peek_position(); | 2344 int pos = peek_position(); |
| 2312 bool starts_with_idenfifier = peek_any_identifier(); | 2345 bool starts_with_idenfifier = peek_any_identifier(); |
| 2313 Expression* expr = ParseExpression(true, CHECK_OK); | 2346 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2314 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2347 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
| 2315 expr->AsVariableProxy() != NULL && | 2348 expr->AsVariableProxy() != NULL && |
| 2316 !expr->AsVariableProxy()->is_this()) { | 2349 !expr->AsVariableProxy()->is_this()) { |
| 2317 // Expression is a single identifier, and not, e.g., a parenthesized | 2350 // Expression is a single identifier, and not, e.g., a parenthesized |
| 2318 // identifier. | 2351 // identifier. |
| 2319 VariableProxy* var = expr->AsVariableProxy(); | 2352 VariableProxy* var = expr->AsVariableProxy(); |
| 2320 Handle<String> label = var->name(); | 2353 ParserSymbolTable::Symbol* label = var->raw_name(); |
| 2321 // TODO(1240780): We don't check for redeclaration of labels | 2354 // TODO(1240780): We don't check for redeclaration of labels |
| 2322 // during preparsing since keeping track of the set of active | 2355 // during preparsing since keeping track of the set of active |
| 2323 // labels requires nontrivial changes to the way scopes are | 2356 // labels requires nontrivial changes to the way scopes are |
| 2324 // structured. However, these are probably changes we want to | 2357 // structured. However, these are probably changes we want to |
| 2325 // make later anyway so we should go back and fix this then. | 2358 // make later anyway so we should go back and fix this then. |
| 2326 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2359 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
| 2327 ParserTraits::ReportMessage("label_redeclaration", label); | 2360 ParserTraits::ReportMessage("label_redeclaration", label); |
| 2328 *ok = false; | 2361 *ok = false; |
| 2329 return NULL; | 2362 return NULL; |
| 2330 } | 2363 } |
| 2331 if (labels == NULL) { | 2364 if (labels == NULL) { |
| 2332 labels = new(zone()) ZoneStringList(4, zone()); | 2365 labels = new(zone()) ZoneList<ParserSymbolTable::Symbol*>(4, zone()); |
| 2333 } | 2366 } |
| 2334 labels->Add(label, zone()); | 2367 labels->Add(label, zone()); |
| 2335 // Remove the "ghost" variable that turned out to be a label | 2368 // Remove the "ghost" variable that turned out to be a label |
| 2336 // from the top scope. This way, we don't try to resolve it | 2369 // from the top scope. This way, we don't try to resolve it |
| 2337 // during the scope processing. | 2370 // during the scope processing. |
| 2338 scope_->RemoveUnresolved(var); | 2371 scope_->RemoveUnresolved(var); |
| 2339 Expect(Token::COLON, CHECK_OK); | 2372 Expect(Token::COLON, CHECK_OK); |
| 2340 return ParseStatement(labels, ok); | 2373 return ParseStatement(labels, ok); |
| 2341 } | 2374 } |
| 2342 | 2375 |
| 2343 // If we have an extension, we allow a native function declaration. | 2376 // If we have an extension, we allow a native function declaration. |
| 2344 // A native function declaration starts with "native function" with | 2377 // A native function declaration starts with "native function" with |
| 2345 // no line-terminator between the two words. | 2378 // no line-terminator between the two words. |
| 2346 if (extension_ != NULL && | 2379 if (extension_ != NULL && |
| 2347 peek() == Token::FUNCTION && | 2380 peek() == Token::FUNCTION && |
| 2348 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2381 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2349 expr != NULL && | 2382 expr != NULL && |
| 2350 expr->AsVariableProxy() != NULL && | 2383 expr->AsVariableProxy() != NULL && |
| 2351 String::Equals(isolate()->factory()->native_string(), | 2384 expr->AsVariableProxy()->raw_name() == symbol_table_->native_string() && |
| 2352 expr->AsVariableProxy()->name()) && | |
| 2353 !scanner()->literal_contains_escapes()) { | 2385 !scanner()->literal_contains_escapes()) { |
| 2354 return ParseNativeDeclaration(ok); | 2386 return ParseNativeDeclaration(ok); |
| 2355 } | 2387 } |
| 2356 | 2388 |
| 2357 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2389 // Parsed expression statement, or the context-sensitive 'module' keyword. |
| 2358 // Only expect semicolon in the former case. | 2390 // Only expect semicolon in the former case. |
| 2359 if (!FLAG_harmony_modules || | 2391 if (!FLAG_harmony_modules || |
| 2360 peek() != Token::IDENTIFIER || | 2392 peek() != Token::IDENTIFIER || |
| 2361 scanner()->HasAnyLineTerminatorBeforeNext() || | 2393 scanner()->HasAnyLineTerminatorBeforeNext() || |
| 2362 expr->AsVariableProxy() == NULL || | 2394 expr->AsVariableProxy() == NULL || |
| 2363 !String::Equals(isolate()->factory()->module_string(), | 2395 expr->AsVariableProxy()->raw_name() != symbol_table_->module_string() || |
| 2364 expr->AsVariableProxy()->name()) || | |
| 2365 scanner()->literal_contains_escapes()) { | 2396 scanner()->literal_contains_escapes()) { |
| 2366 ExpectSemicolon(CHECK_OK); | 2397 ExpectSemicolon(CHECK_OK); |
| 2367 } | 2398 } |
| 2368 return factory()->NewExpressionStatement(expr, pos); | 2399 return factory()->NewExpressionStatement(expr, pos); |
| 2369 } | 2400 } |
| 2370 | 2401 |
| 2371 | 2402 |
| 2372 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2403 IfStatement* Parser::ParseIfStatement( |
| 2404 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2373 // IfStatement :: | 2405 // IfStatement :: |
| 2374 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2406 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2375 | 2407 |
| 2376 int pos = peek_position(); | 2408 int pos = peek_position(); |
| 2377 Expect(Token::IF, CHECK_OK); | 2409 Expect(Token::IF, CHECK_OK); |
| 2378 Expect(Token::LPAREN, CHECK_OK); | 2410 Expect(Token::LPAREN, CHECK_OK); |
| 2379 Expression* condition = ParseExpression(true, CHECK_OK); | 2411 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2380 Expect(Token::RPAREN, CHECK_OK); | 2412 Expect(Token::RPAREN, CHECK_OK); |
| 2381 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2413 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2382 Statement* else_statement = NULL; | 2414 Statement* else_statement = NULL; |
| 2383 if (peek() == Token::ELSE) { | 2415 if (peek() == Token::ELSE) { |
| 2384 Next(); | 2416 Next(); |
| 2385 else_statement = ParseStatement(labels, CHECK_OK); | 2417 else_statement = ParseStatement(labels, CHECK_OK); |
| 2386 } else { | 2418 } else { |
| 2387 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2419 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2388 } | 2420 } |
| 2389 return factory()->NewIfStatement( | 2421 return factory()->NewIfStatement( |
| 2390 condition, then_statement, else_statement, pos); | 2422 condition, then_statement, else_statement, pos); |
| 2391 } | 2423 } |
| 2392 | 2424 |
| 2393 | 2425 |
| 2394 Statement* Parser::ParseContinueStatement(bool* ok) { | 2426 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2395 // ContinueStatement :: | 2427 // ContinueStatement :: |
| 2396 // 'continue' Identifier? ';' | 2428 // 'continue' Identifier? ';' |
| 2397 | 2429 |
| 2398 int pos = peek_position(); | 2430 int pos = peek_position(); |
| 2399 Expect(Token::CONTINUE, CHECK_OK); | 2431 Expect(Token::CONTINUE, CHECK_OK); |
| 2400 Handle<String> label = Handle<String>::null(); | 2432 ParserSymbolTable::Symbol* label = NULL; |
| 2401 Token::Value tok = peek(); | 2433 Token::Value tok = peek(); |
| 2402 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2434 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2403 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2435 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2404 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2436 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2405 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2437 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2406 } | 2438 } |
| 2407 IterationStatement* target = NULL; | 2439 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); |
| 2408 target = LookupContinueTarget(label, CHECK_OK); | |
| 2409 if (target == NULL) { | 2440 if (target == NULL) { |
| 2410 // Illegal continue statement. | 2441 // Illegal continue statement. |
| 2411 const char* message = "illegal_continue"; | 2442 if (label != NULL) { |
| 2412 if (!label.is_null()) { | 2443 ParserTraits::ReportMessageAt(scanner()->location(), "unknown_label", |
| 2413 message = "unknown_label"; | 2444 label); |
| 2445 } else { |
| 2446 ParserTraits::ReportMessageAt(scanner()->location(), "illegal_continue"); |
| 2414 } | 2447 } |
| 2415 ParserTraits::ReportMessageAt(scanner()->location(), message, label); | |
| 2416 *ok = false; | 2448 *ok = false; |
| 2417 return NULL; | 2449 return NULL; |
| 2418 } | 2450 } |
| 2419 ExpectSemicolon(CHECK_OK); | 2451 ExpectSemicolon(CHECK_OK); |
| 2420 return factory()->NewContinueStatement(target, pos); | 2452 return factory()->NewContinueStatement(target, pos); |
| 2421 } | 2453 } |
| 2422 | 2454 |
| 2423 | 2455 |
| 2424 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2456 Statement* Parser::ParseBreakStatement( |
| 2457 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2425 // BreakStatement :: | 2458 // BreakStatement :: |
| 2426 // 'break' Identifier? ';' | 2459 // 'break' Identifier? ';' |
| 2427 | 2460 |
| 2428 int pos = peek_position(); | 2461 int pos = peek_position(); |
| 2429 Expect(Token::BREAK, CHECK_OK); | 2462 Expect(Token::BREAK, CHECK_OK); |
| 2430 Handle<String> label; | 2463 ParserSymbolTable::Symbol* label = NULL; |
| 2431 Token::Value tok = peek(); | 2464 Token::Value tok = peek(); |
| 2432 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2465 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2433 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2466 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2434 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2467 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2435 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2468 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2436 } | 2469 } |
| 2437 // Parse labeled break statements that target themselves into | 2470 // Parse labeled break statements that target themselves into |
| 2438 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2471 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2439 if (!label.is_null() && ContainsLabel(labels, label)) { | 2472 if (label != NULL && ContainsLabel(labels, label)) { |
| 2440 ExpectSemicolon(CHECK_OK); | 2473 ExpectSemicolon(CHECK_OK); |
| 2441 return factory()->NewEmptyStatement(pos); | 2474 return factory()->NewEmptyStatement(pos); |
| 2442 } | 2475 } |
| 2443 BreakableStatement* target = NULL; | 2476 BreakableStatement* target = NULL; |
| 2444 target = LookupBreakTarget(label, CHECK_OK); | 2477 target = LookupBreakTarget(label, CHECK_OK); |
| 2445 if (target == NULL) { | 2478 if (target == NULL) { |
| 2446 // Illegal break statement. | 2479 // Illegal break statement. |
| 2447 const char* message = "illegal_break"; | 2480 if (label != NULL) { |
| 2448 if (!label.is_null()) { | 2481 ParserTraits::ReportMessage("unknown_label", label); |
| 2449 message = "unknown_label"; | 2482 } else { |
| 2483 ParserTraits::ReportMessage("illegal_break"); |
| 2450 } | 2484 } |
| 2451 ParserTraits::ReportMessageAt(scanner()->location(), message, label); | |
| 2452 *ok = false; | 2485 *ok = false; |
| 2453 return NULL; | 2486 return NULL; |
| 2454 } | 2487 } |
| 2455 ExpectSemicolon(CHECK_OK); | 2488 ExpectSemicolon(CHECK_OK); |
| 2456 return factory()->NewBreakStatement(target, pos); | 2489 return factory()->NewBreakStatement(target, pos); |
| 2457 } | 2490 } |
| 2458 | 2491 |
| 2459 | 2492 |
| 2460 Statement* Parser::ParseReturnStatement(bool* ok) { | 2493 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2461 // ReturnStatement :: | 2494 // ReturnStatement :: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2484 function_state_->generator_object_variable()); | 2517 function_state_->generator_object_variable()); |
| 2485 Expression* yield = factory()->NewYield( | 2518 Expression* yield = factory()->NewYield( |
| 2486 generator, return_value, Yield::FINAL, loc.beg_pos); | 2519 generator, return_value, Yield::FINAL, loc.beg_pos); |
| 2487 result = factory()->NewExpressionStatement(yield, loc.beg_pos); | 2520 result = factory()->NewExpressionStatement(yield, loc.beg_pos); |
| 2488 } else { | 2521 } else { |
| 2489 result = factory()->NewReturnStatement(return_value, loc.beg_pos); | 2522 result = factory()->NewReturnStatement(return_value, loc.beg_pos); |
| 2490 } | 2523 } |
| 2491 | 2524 |
| 2492 Scope* decl_scope = scope_->DeclarationScope(); | 2525 Scope* decl_scope = scope_->DeclarationScope(); |
| 2493 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { | 2526 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
| 2494 ReportMessageAt(loc, "illegal_return"); | 2527 ParserTraits::ReportMessageAt(loc, "illegal_return"); |
| 2495 *ok = false; | 2528 *ok = false; |
| 2496 return NULL; | 2529 return NULL; |
| 2497 } | 2530 } |
| 2498 return result; | 2531 return result; |
| 2499 } | 2532 } |
| 2500 | 2533 |
| 2501 | 2534 |
| 2502 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2535 Statement* Parser::ParseWithStatement( |
| 2536 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2503 // WithStatement :: | 2537 // WithStatement :: |
| 2504 // 'with' '(' Expression ')' Statement | 2538 // 'with' '(' Expression ')' Statement |
| 2505 | 2539 |
| 2506 Expect(Token::WITH, CHECK_OK); | 2540 Expect(Token::WITH, CHECK_OK); |
| 2507 int pos = position(); | 2541 int pos = position(); |
| 2508 | 2542 |
| 2509 if (strict_mode() == STRICT) { | 2543 if (strict_mode() == STRICT) { |
| 2510 ReportMessage("strict_mode_with"); | 2544 ReportMessage("strict_mode_with"); |
| 2511 *ok = false; | 2545 *ok = false; |
| 2512 return NULL; | 2546 return NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2554 peek() != Token::DEFAULT && | 2588 peek() != Token::DEFAULT && |
| 2555 peek() != Token::RBRACE) { | 2589 peek() != Token::RBRACE) { |
| 2556 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2590 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2557 statements->Add(stat, zone()); | 2591 statements->Add(stat, zone()); |
| 2558 } | 2592 } |
| 2559 | 2593 |
| 2560 return factory()->NewCaseClause(label, statements, pos); | 2594 return factory()->NewCaseClause(label, statements, pos); |
| 2561 } | 2595 } |
| 2562 | 2596 |
| 2563 | 2597 |
| 2564 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2598 SwitchStatement* Parser::ParseSwitchStatement( |
| 2565 bool* ok) { | 2599 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2566 // SwitchStatement :: | 2600 // SwitchStatement :: |
| 2567 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2601 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2568 | 2602 |
| 2569 SwitchStatement* statement = | 2603 SwitchStatement* statement = |
| 2570 factory()->NewSwitchStatement(labels, peek_position()); | 2604 factory()->NewSwitchStatement(labels, peek_position()); |
| 2571 Target target(&this->target_stack_, statement); | 2605 Target target(&this->target_stack_, statement); |
| 2572 | 2606 |
| 2573 Expect(Token::SWITCH, CHECK_OK); | 2607 Expect(Token::SWITCH, CHECK_OK); |
| 2574 Expect(Token::LPAREN, CHECK_OK); | 2608 Expect(Token::LPAREN, CHECK_OK); |
| 2575 Expression* tag = ParseExpression(true, CHECK_OK); | 2609 Expression* tag = ParseExpression(true, CHECK_OK); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 } | 2672 } |
| 2639 | 2673 |
| 2640 // If we can break out from the catch block and there is a finally block, | 2674 // If we can break out from the catch block and there is a finally block, |
| 2641 // then we will need to collect escaping targets from the catch | 2675 // then we will need to collect escaping targets from the catch |
| 2642 // block. Since we don't know yet if there will be a finally block, we | 2676 // block. Since we don't know yet if there will be a finally block, we |
| 2643 // always collect the targets. | 2677 // always collect the targets. |
| 2644 TargetCollector catch_collector(zone()); | 2678 TargetCollector catch_collector(zone()); |
| 2645 Scope* catch_scope = NULL; | 2679 Scope* catch_scope = NULL; |
| 2646 Variable* catch_variable = NULL; | 2680 Variable* catch_variable = NULL; |
| 2647 Block* catch_block = NULL; | 2681 Block* catch_block = NULL; |
| 2648 Handle<String> name; | 2682 ParserSymbolTable::Symbol* name = NULL; |
| 2649 if (tok == Token::CATCH) { | 2683 if (tok == Token::CATCH) { |
| 2650 Consume(Token::CATCH); | 2684 Consume(Token::CATCH); |
| 2651 | 2685 |
| 2652 Expect(Token::LPAREN, CHECK_OK); | 2686 Expect(Token::LPAREN, CHECK_OK); |
| 2653 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2687 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2654 catch_scope->set_start_position(scanner()->location().beg_pos); | 2688 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2655 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2689 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2656 | 2690 |
| 2657 Expect(Token::RPAREN, CHECK_OK); | 2691 Expect(Token::RPAREN, CHECK_OK); |
| 2658 | 2692 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2708 index, try_block, finally_block, pos); | 2742 index, try_block, finally_block, pos); |
| 2709 // Combine the jump targets of the try block and the possible catch block. | 2743 // Combine the jump targets of the try block and the possible catch block. |
| 2710 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2744 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2711 } | 2745 } |
| 2712 | 2746 |
| 2713 result->set_escaping_targets(try_collector.targets()); | 2747 result->set_escaping_targets(try_collector.targets()); |
| 2714 return result; | 2748 return result; |
| 2715 } | 2749 } |
| 2716 | 2750 |
| 2717 | 2751 |
| 2718 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2752 DoWhileStatement* Parser::ParseDoWhileStatement( |
| 2719 bool* ok) { | 2753 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2720 // DoStatement :: | 2754 // DoStatement :: |
| 2721 // 'do' Statement 'while' '(' Expression ')' ';' | 2755 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2722 | 2756 |
| 2723 DoWhileStatement* loop = | 2757 DoWhileStatement* loop = |
| 2724 factory()->NewDoWhileStatement(labels, peek_position()); | 2758 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2725 Target target(&this->target_stack_, loop); | 2759 Target target(&this->target_stack_, loop); |
| 2726 | 2760 |
| 2727 Expect(Token::DO, CHECK_OK); | 2761 Expect(Token::DO, CHECK_OK); |
| 2728 Statement* body = ParseStatement(NULL, CHECK_OK); | 2762 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2729 Expect(Token::WHILE, CHECK_OK); | 2763 Expect(Token::WHILE, CHECK_OK); |
| 2730 Expect(Token::LPAREN, CHECK_OK); | 2764 Expect(Token::LPAREN, CHECK_OK); |
| 2731 | 2765 |
| 2732 Expression* cond = ParseExpression(true, CHECK_OK); | 2766 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2733 Expect(Token::RPAREN, CHECK_OK); | 2767 Expect(Token::RPAREN, CHECK_OK); |
| 2734 | 2768 |
| 2735 // Allow do-statements to be terminated with and without | 2769 // Allow do-statements to be terminated with and without |
| 2736 // semi-colons. This allows code such as 'do;while(0)return' to | 2770 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2737 // parse, which would not be the case if we had used the | 2771 // parse, which would not be the case if we had used the |
| 2738 // ExpectSemicolon() functionality here. | 2772 // ExpectSemicolon() functionality here. |
| 2739 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2773 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2740 | 2774 |
| 2741 if (loop != NULL) loop->Initialize(cond, body); | 2775 if (loop != NULL) loop->Initialize(cond, body); |
| 2742 return loop; | 2776 return loop; |
| 2743 } | 2777 } |
| 2744 | 2778 |
| 2745 | 2779 |
| 2746 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2780 WhileStatement* Parser::ParseWhileStatement( |
| 2781 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2747 // WhileStatement :: | 2782 // WhileStatement :: |
| 2748 // 'while' '(' Expression ')' Statement | 2783 // 'while' '(' Expression ')' Statement |
| 2749 | 2784 |
| 2750 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2785 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2751 Target target(&this->target_stack_, loop); | 2786 Target target(&this->target_stack_, loop); |
| 2752 | 2787 |
| 2753 Expect(Token::WHILE, CHECK_OK); | 2788 Expect(Token::WHILE, CHECK_OK); |
| 2754 Expect(Token::LPAREN, CHECK_OK); | 2789 Expect(Token::LPAREN, CHECK_OK); |
| 2755 Expression* cond = ParseExpression(true, CHECK_OK); | 2790 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2756 Expect(Token::RPAREN, CHECK_OK); | 2791 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2777 | 2812 |
| 2778 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2813 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2779 Expression* each, | 2814 Expression* each, |
| 2780 Expression* subject, | 2815 Expression* subject, |
| 2781 Statement* body) { | 2816 Statement* body) { |
| 2782 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2817 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2783 | 2818 |
| 2784 if (for_of != NULL) { | 2819 if (for_of != NULL) { |
| 2785 Factory* heap_factory = isolate()->factory(); | 2820 Factory* heap_factory = isolate()->factory(); |
| 2786 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2821 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
| 2787 heap_factory->dot_iterator_string()); | 2822 symbol_table_->dot_iterator_string()); |
| 2788 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2823 Variable* result = scope_->DeclarationScope()->NewTemporary( |
| 2789 heap_factory->dot_result_string()); | 2824 symbol_table_->dot_result_string()); |
| 2790 | 2825 |
| 2791 Expression* assign_iterator; | 2826 Expression* assign_iterator; |
| 2792 Expression* next_result; | 2827 Expression* next_result; |
| 2793 Expression* result_done; | 2828 Expression* result_done; |
| 2794 Expression* assign_each; | 2829 Expression* assign_each; |
| 2795 | 2830 |
| 2796 // var iterator = iterable; | 2831 // var iterator = iterable; |
| 2797 { | 2832 { |
| 2798 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2833 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2799 assign_iterator = factory()->NewAssignment( | 2834 assign_iterator = factory()->NewAssignment( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 } | 2872 } |
| 2838 | 2873 |
| 2839 for_of->Initialize(each, subject, body, | 2874 for_of->Initialize(each, subject, body, |
| 2840 assign_iterator, next_result, result_done, assign_each); | 2875 assign_iterator, next_result, result_done, assign_each); |
| 2841 } else { | 2876 } else { |
| 2842 stmt->Initialize(each, subject, body); | 2877 stmt->Initialize(each, subject, body); |
| 2843 } | 2878 } |
| 2844 } | 2879 } |
| 2845 | 2880 |
| 2846 | 2881 |
| 2847 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2882 Statement* Parser::ParseForStatement( |
| 2883 ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
| 2848 // ForStatement :: | 2884 // ForStatement :: |
| 2849 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2885 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2850 | 2886 |
| 2851 int pos = peek_position(); | 2887 int pos = peek_position(); |
| 2852 Statement* init = NULL; | 2888 Statement* init = NULL; |
| 2853 | 2889 |
| 2854 // Create an in-between scope for let-bound iteration variables. | 2890 // Create an in-between scope for let-bound iteration variables. |
| 2855 Scope* saved_scope = scope_; | 2891 Scope* saved_scope = scope_; |
| 2856 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 2892 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 2857 scope_ = for_scope; | 2893 scope_ = for_scope; |
| 2858 | 2894 |
| 2859 Expect(Token::FOR, CHECK_OK); | 2895 Expect(Token::FOR, CHECK_OK); |
| 2860 Expect(Token::LPAREN, CHECK_OK); | 2896 Expect(Token::LPAREN, CHECK_OK); |
| 2861 for_scope->set_start_position(scanner()->location().beg_pos); | 2897 for_scope->set_start_position(scanner()->location().beg_pos); |
| 2862 if (peek() != Token::SEMICOLON) { | 2898 if (peek() != Token::SEMICOLON) { |
| 2863 if (peek() == Token::VAR || peek() == Token::CONST) { | 2899 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2864 bool is_const = peek() == Token::CONST; | 2900 bool is_const = peek() == Token::CONST; |
| 2865 Handle<String> name; | 2901 ParserSymbolTable::Symbol* name = NULL; |
| 2866 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2902 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2867 Block* variable_statement = | 2903 Block* variable_statement = |
| 2868 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2904 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2869 CHECK_OK); | 2905 CHECK_OK); |
| 2870 bool accept_OF = decl_props == kHasNoInitializers; | 2906 bool accept_OF = decl_props == kHasNoInitializers; |
| 2871 ForEachStatement::VisitMode mode; | 2907 ForEachStatement::VisitMode mode; |
| 2872 | 2908 |
| 2873 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2909 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { |
| 2874 Interface* interface = | 2910 Interface* interface = |
| 2875 is_const ? Interface::NewConst() : Interface::NewValue(); | 2911 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2876 ForEachStatement* loop = | 2912 ForEachStatement* loop = |
| 2877 factory()->NewForEachStatement(mode, labels, pos); | 2913 factory()->NewForEachStatement(mode, labels, pos); |
| 2878 Target target(&this->target_stack_, loop); | 2914 Target target(&this->target_stack_, loop); |
| 2879 | 2915 |
| 2880 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2916 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2881 Expect(Token::RPAREN, CHECK_OK); | 2917 Expect(Token::RPAREN, CHECK_OK); |
| 2882 | 2918 |
| 2883 VariableProxy* each = | 2919 VariableProxy* each = |
| 2884 scope_->NewUnresolved(factory(), name, interface); | 2920 scope_->NewUnresolved(factory(), name, interface); |
| 2885 Statement* body = ParseStatement(NULL, CHECK_OK); | 2921 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2886 InitializeForEachStatement(loop, each, enumerable, body); | 2922 InitializeForEachStatement(loop, each, enumerable, body); |
| 2887 Block* result = | 2923 Block* result = |
| 2888 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2924 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2889 result->AddStatement(variable_statement, zone()); | 2925 result->AddStatement(variable_statement, zone()); |
| 2890 result->AddStatement(loop, zone()); | 2926 result->AddStatement(loop, zone()); |
| 2891 scope_ = saved_scope; | 2927 scope_ = saved_scope; |
| 2892 for_scope->set_end_position(scanner()->location().end_pos); | 2928 for_scope->set_end_position(scanner()->location().end_pos); |
| 2893 for_scope = for_scope->FinalizeBlockScope(); | 2929 for_scope = for_scope->FinalizeBlockScope(); |
| 2894 ASSERT(for_scope == NULL); | 2930 ASSERT(for_scope == NULL); |
| 2895 // Parsed for-in loop w/ variable/const declaration. | 2931 // Parsed for-in loop w/ variable/const declaration. |
| 2896 return result; | 2932 return result; |
| 2897 } else { | 2933 } else { |
| 2898 init = variable_statement; | 2934 init = variable_statement; |
| 2899 } | 2935 } |
| 2900 } else if (peek() == Token::LET) { | 2936 } else if (peek() == Token::LET) { |
| 2901 Handle<String> name; | 2937 ParserSymbolTable::Symbol* name = NULL; |
| 2902 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2938 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2903 Block* variable_statement = | 2939 Block* variable_statement = |
| 2904 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2940 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2905 CHECK_OK); | 2941 CHECK_OK); |
| 2906 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2942 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 2907 bool accept_OF = decl_props == kHasNoInitializers; | 2943 bool accept_OF = decl_props == kHasNoInitializers; |
| 2908 ForEachStatement::VisitMode mode; | 2944 ForEachStatement::VisitMode mode; |
| 2909 | 2945 |
| 2910 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 2946 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
| 2911 // Rewrite a for-in statement of the form | 2947 // Rewrite a for-in statement of the form |
| 2912 // | 2948 // |
| 2913 // for (let x in e) b | 2949 // for (let x in e) b |
| 2914 // | 2950 // |
| 2915 // into | 2951 // into |
| 2916 // | 2952 // |
| 2917 // <let x' be a temporary variable> | 2953 // <let x' be a temporary variable> |
| 2918 // for (x' in e) { | 2954 // for (x' in e) { |
| 2919 // let x; | 2955 // let x; |
| 2920 // x = x'; | 2956 // x = x'; |
| 2921 // b; | 2957 // b; |
| 2922 // } | 2958 // } |
| 2923 | 2959 |
| 2924 // TODO(keuchel): Move the temporary variable to the block scope, after | 2960 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2925 // implementing stack allocated block scoped variables. | 2961 // implementing stack allocated block scoped variables. |
| 2926 Factory* heap_factory = isolate()->factory(); | 2962 // Factory* heap_factory = isolate()->factory(); |
| 2927 Handle<String> tempstr; | 2963 // FIXME: do this somehow independent of the heap. |
| 2928 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 2964 // ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 2929 isolate(), tempstr, | 2965 // isolate(), tempstr, |
| 2930 heap_factory->NewConsString(heap_factory->dot_for_string(), name), | 2966 // heap_factory->NewConsString(heap_factory->dot_for_string(), name)
, |
| 2931 0); | 2967 // 0); |
| 2932 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2968 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 2933 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); | 2969 symbol_table_->dot_for_string()); |
| 2934 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2970 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2935 ForEachStatement* loop = | 2971 ForEachStatement* loop = |
| 2936 factory()->NewForEachStatement(mode, labels, pos); | 2972 factory()->NewForEachStatement(mode, labels, pos); |
| 2937 Target target(&this->target_stack_, loop); | 2973 Target target(&this->target_stack_, loop); |
| 2938 | 2974 |
| 2939 // The expression does not see the loop variable. | 2975 // The expression does not see the loop variable. |
| 2940 scope_ = saved_scope; | 2976 scope_ = saved_scope; |
| 2941 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2977 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2942 scope_ = for_scope; | 2978 scope_ = for_scope; |
| 2943 Expect(Token::RPAREN, CHECK_OK); | 2979 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3054 // DebuggerStatement :: | 3090 // DebuggerStatement :: |
| 3055 // 'debugger' ';' | 3091 // 'debugger' ';' |
| 3056 | 3092 |
| 3057 int pos = peek_position(); | 3093 int pos = peek_position(); |
| 3058 Expect(Token::DEBUGGER, CHECK_OK); | 3094 Expect(Token::DEBUGGER, CHECK_OK); |
| 3059 ExpectSemicolon(CHECK_OK); | 3095 ExpectSemicolon(CHECK_OK); |
| 3060 return factory()->NewDebuggerStatement(pos); | 3096 return factory()->NewDebuggerStatement(pos); |
| 3061 } | 3097 } |
| 3062 | 3098 |
| 3063 | 3099 |
| 3064 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { | 3100 void Parser::ReportInvalidCachedData(ParserSymbolTable::Symbol* name, |
| 3101 bool* ok) { |
| 3065 ParserTraits::ReportMessage("invalid_cached_data_function", name); | 3102 ParserTraits::ReportMessage("invalid_cached_data_function", name); |
| 3066 *ok = false; | 3103 *ok = false; |
| 3067 } | 3104 } |
| 3068 | 3105 |
| 3069 | 3106 |
| 3070 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3107 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3071 if (expression->AsLiteral() != NULL) return true; | 3108 if (expression->AsLiteral() != NULL) return true; |
| 3072 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3109 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3073 return lit != NULL && lit->is_simple(); | 3110 return lit != NULL && lit->is_simple(); |
| 3074 } | 3111 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3104 return static_cast<LiteralType>(literal_type->value()); | 3141 return static_cast<LiteralType>(literal_type->value()); |
| 3105 } | 3142 } |
| 3106 | 3143 |
| 3107 | 3144 |
| 3108 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3145 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| 3109 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3146 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
| 3110 } | 3147 } |
| 3111 | 3148 |
| 3112 | 3149 |
| 3113 FunctionLiteral* Parser::ParseFunctionLiteral( | 3150 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3114 Handle<String> function_name, | 3151 ParserSymbolTable::Symbol* function_name, |
| 3115 Scanner::Location function_name_location, | 3152 Scanner::Location function_name_location, |
| 3116 bool name_is_strict_reserved, | 3153 bool name_is_strict_reserved, |
| 3117 bool is_generator, | 3154 bool is_generator, |
| 3118 int function_token_pos, | 3155 int function_token_pos, |
| 3119 FunctionLiteral::FunctionType function_type, | 3156 FunctionLiteral::FunctionType function_type, |
| 3120 bool* ok) { | 3157 bool* ok) { |
| 3121 // Function :: | 3158 // Function :: |
| 3122 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3159 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3123 | 3160 |
| 3124 int pos = function_token_pos == RelocInfo::kNoPosition | 3161 int pos = function_token_pos == RelocInfo::kNoPosition |
| 3125 ? peek_position() : function_token_pos; | 3162 ? peek_position() : function_token_pos; |
| 3126 | 3163 |
| 3127 // Anonymous functions were passed either the empty symbol or a null | 3164 // Anonymous functions were passed either the empty symbol or a null |
| 3128 // handle as the function name. Remember if we were passed a non-empty | 3165 // handle as the function name. Remember if we were passed a non-empty |
| 3129 // handle to decide whether to invoke function name inference. | 3166 // handle to decide whether to invoke function name inference. |
| 3130 bool should_infer_name = function_name.is_null(); | 3167 bool should_infer_name = function_name == NULL; |
| 3131 | 3168 |
| 3132 // We want a non-null handle as the function name. | 3169 // We want a non-null handle as the function name. |
| 3133 if (should_infer_name) { | 3170 if (should_infer_name) { |
| 3134 function_name = isolate()->factory()->empty_string(); | 3171 function_name = symbol_table_->empty_string(); |
| 3135 } | 3172 } |
| 3136 | 3173 |
| 3137 int num_parameters = 0; | 3174 int num_parameters = 0; |
| 3138 // Function declarations are function scoped in normal mode, so they are | 3175 // Function declarations are function scoped in normal mode, so they are |
| 3139 // hoisted. In harmony block scoping mode they are block scoped, so they | 3176 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3140 // are not hoisted. | 3177 // are not hoisted. |
| 3141 // | 3178 // |
| 3142 // One tricky case are function declarations in a local sloppy-mode eval: | 3179 // One tricky case are function declarations in a local sloppy-mode eval: |
| 3143 // their declaration is hoisted, but they still see the local scope. E.g., | 3180 // their declaration is hoisted, but they still see the local scope. E.g., |
| 3144 // | 3181 // |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 | 3225 |
| 3189 if (is_generator) { | 3226 if (is_generator) { |
| 3190 // For generators, allocating variables in contexts is currently a win | 3227 // For generators, allocating variables in contexts is currently a win |
| 3191 // because it minimizes the work needed to suspend and resume an | 3228 // because it minimizes the work needed to suspend and resume an |
| 3192 // activation. | 3229 // activation. |
| 3193 scope_->ForceContextAllocation(); | 3230 scope_->ForceContextAllocation(); |
| 3194 | 3231 |
| 3195 // Calling a generator returns a generator object. That object is stored | 3232 // Calling a generator returns a generator object. That object is stored |
| 3196 // in a temporary variable, a definition that is used by "yield" | 3233 // in a temporary variable, a definition that is used by "yield" |
| 3197 // expressions. This also marks the FunctionState as a generator. | 3234 // expressions. This also marks the FunctionState as a generator. |
| 3198 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3235 ParserSymbolTable::Symbol* generator_name = |
| 3199 isolate()->factory()->dot_generator_object_string()); | 3236 symbol_table_->GetOneByteSymbol(Vector<const uint8_t>( |
| 3237 reinterpret_cast<const unsigned char*>(".generator"), 10)); |
| 3238 Variable* temp = scope_->DeclarationScope()->NewTemporary(generator_name); |
| 3200 function_state.set_generator_object_variable(temp); | 3239 function_state.set_generator_object_variable(temp); |
| 3201 } | 3240 } |
| 3202 | 3241 |
| 3203 // FormalParameterList :: | 3242 // FormalParameterList :: |
| 3204 // '(' (Identifier)*[','] ')' | 3243 // '(' (Identifier)*[','] ')' |
| 3205 Expect(Token::LPAREN, CHECK_OK); | 3244 Expect(Token::LPAREN, CHECK_OK); |
| 3206 scope->set_start_position(scanner()->location().beg_pos); | 3245 scope->set_start_position(scanner()->location().beg_pos); |
| 3207 | 3246 |
| 3208 // We don't yet know if the function will be strict, so we cannot yet | 3247 // We don't yet know if the function will be strict, so we cannot yet |
| 3209 // produce errors for parameter names or duplicates. However, we remember | 3248 // produce errors for parameter names or duplicates. However, we remember |
| 3210 // the locations of these errors if they occur and produce the errors later. | 3249 // the locations of these errors if they occur and produce the errors later. |
| 3211 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3250 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 3212 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3251 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 3213 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3252 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3214 | 3253 |
| 3215 bool done = (peek() == Token::RPAREN); | 3254 bool done = (peek() == Token::RPAREN); |
| 3216 while (!done) { | 3255 while (!done) { |
| 3217 bool is_strict_reserved = false; | 3256 bool is_strict_reserved = false; |
| 3218 Handle<String> param_name = | 3257 ParserSymbolTable::Symbol* param_name = |
| 3219 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3258 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3220 | 3259 |
| 3221 // Store locations for possible future error reports. | 3260 // Store locations for possible future error reports. |
| 3222 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3261 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 3223 eval_args_error_log = scanner()->location(); | 3262 eval_args_error_log = scanner()->location(); |
| 3224 } | 3263 } |
| 3225 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3264 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3226 reserved_loc = scanner()->location(); | 3265 reserved_loc = scanner()->location(); |
| 3227 } | 3266 } |
| 3228 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3267 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 3229 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3268 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3230 dupe_error_loc = scanner()->location(); | 3269 dupe_error_loc = scanner()->location(); |
| 3231 } | 3270 } |
| 3232 | 3271 |
| 3233 scope_->DeclareParameter(param_name, VAR); | 3272 scope_->DeclareParameter(param_name, VAR); |
| 3234 num_parameters++; | 3273 num_parameters++; |
| 3235 if (num_parameters > Code::kMaxArguments) { | 3274 if (num_parameters > Code::kMaxArguments) { |
| 3236 ReportMessageAt(scanner()->location(), "too_many_parameters"); | 3275 ReportMessage("too_many_parameters"); |
| 3237 *ok = false; | 3276 *ok = false; |
| 3238 return NULL; | 3277 return NULL; |
| 3239 } | 3278 } |
| 3240 done = (peek() == Token::RPAREN); | 3279 done = (peek() == Token::RPAREN); |
| 3241 if (!done) Expect(Token::COMMA, CHECK_OK); | 3280 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3242 } | 3281 } |
| 3243 Expect(Token::RPAREN, CHECK_OK); | 3282 Expect(Token::RPAREN, CHECK_OK); |
| 3244 | 3283 |
| 3245 Expect(Token::LBRACE, CHECK_OK); | 3284 Expect(Token::LBRACE, CHECK_OK); |
| 3246 | 3285 |
| 3247 // If we have a named function expression, we add a local variable | 3286 // If we have a named function expression, we add a local variable |
| 3248 // declaration to the body of the function with the name of the | 3287 // declaration to the body of the function with the name of the |
| 3249 // function and let it refer to the function itself (closure). | 3288 // function and let it refer to the function itself (closure). |
| 3250 // NOTE: We create a proxy and resolve it here so that in the | 3289 // NOTE: We create a proxy and resolve it here so that in the |
| 3251 // future we can change the AST to only refer to VariableProxies | 3290 // future we can change the AST to only refer to VariableProxies |
| 3252 // instead of Variables and Proxis as is the case now. | 3291 // instead of Variables and Proxis as is the case now. |
| 3253 Variable* fvar = NULL; | 3292 Variable* fvar = NULL; |
| 3254 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3293 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3255 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3294 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3295 ASSERT(function_name != NULL); |
| 3256 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3296 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3257 fvar_init_op = Token::INIT_CONST; | 3297 fvar_init_op = Token::INIT_CONST; |
| 3258 } | 3298 } |
| 3259 VariableMode fvar_mode = | 3299 VariableMode fvar_mode = |
| 3260 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3300 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
| 3261 : CONST_LEGACY; | 3301 : CONST_LEGACY; |
| 3262 fvar = new(zone()) Variable(scope_, | 3302 fvar = new(zone()) Variable(scope_, |
| 3263 function_name, fvar_mode, true /* is valid LHS */, | 3303 function_name, fvar_mode, true /* is valid LHS */, |
| 3264 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3304 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3265 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3305 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3376 pos); | 3416 pos); |
| 3377 function_literal->set_function_token_position(function_token_pos); | 3417 function_literal->set_function_token_position(function_token_pos); |
| 3378 function_literal->set_ast_properties(&ast_properties); | 3418 function_literal->set_ast_properties(&ast_properties); |
| 3379 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3419 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 3380 | 3420 |
| 3381 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3421 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3382 return function_literal; | 3422 return function_literal; |
| 3383 } | 3423 } |
| 3384 | 3424 |
| 3385 | 3425 |
| 3386 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3426 void Parser::SkipLazyFunctionBody(ParserSymbolTable::Symbol* function_name, |
| 3387 int* materialized_literal_count, | 3427 int* materialized_literal_count, |
| 3388 int* expected_property_count, | 3428 int* expected_property_count, |
| 3389 bool* ok) { | 3429 bool* ok) { |
| 3390 int function_block_pos = position(); | 3430 int function_block_pos = position(); |
| 3391 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3431 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 3392 // If we have cached data, we use it to skip parsing the function body. The | 3432 // If we have cached data, we use it to skip parsing the function body. The |
| 3393 // data contains the information we need to construct the lazy function. | 3433 // data contains the information we need to construct the lazy function. |
| 3394 FunctionEntry entry = | 3434 FunctionEntry entry = |
| 3395 (*cached_data())->GetFunctionEntry(function_block_pos); | 3435 (*cached_data())->GetFunctionEntry(function_block_pos); |
| 3396 if (entry.is_valid()) { | 3436 if (entry.is_valid()) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3455 log_->LogFunction(function_block_pos, body_end, | 3495 log_->LogFunction(function_block_pos, body_end, |
| 3456 *materialized_literal_count, | 3496 *materialized_literal_count, |
| 3457 *expected_property_count, | 3497 *expected_property_count, |
| 3458 scope_->strict_mode()); | 3498 scope_->strict_mode()); |
| 3459 } | 3499 } |
| 3460 } | 3500 } |
| 3461 } | 3501 } |
| 3462 | 3502 |
| 3463 | 3503 |
| 3464 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3504 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3465 Handle<String> function_name, int pos, Variable* fvar, | 3505 ParserSymbolTable::Symbol* function_name, int pos, Variable* fvar, |
| 3466 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3506 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3467 // Everything inside an eagerly parsed function will be parsed eagerly | 3507 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3468 // (see comment above). | 3508 // (see comment above). |
| 3469 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3509 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 3470 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3510 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3471 if (fvar != NULL) { | 3511 if (fvar != NULL) { |
| 3472 VariableProxy* fproxy = scope_->NewUnresolved( | 3512 VariableProxy* fproxy = scope_->NewUnresolved( |
| 3473 factory(), function_name, Interface::NewConst()); | 3513 factory(), function_name, Interface::NewConst()); |
| 3474 fproxy->BindTo(fvar); | 3514 fproxy->BindTo(fvar); |
| 3475 body->Add(factory()->NewExpressionStatement( | 3515 body->Add(factory()->NewExpressionStatement( |
| 3476 factory()->NewAssignment(fvar_init_op, | 3516 factory()->NewAssignment(fvar_init_op, |
| 3477 fproxy, | 3517 fproxy, |
| 3478 factory()->NewThisFunction(pos), | 3518 factory()->NewThisFunction(pos), |
| 3479 RelocInfo::kNoPosition), | 3519 RelocInfo::kNoPosition), |
| 3480 RelocInfo::kNoPosition), zone()); | 3520 RelocInfo::kNoPosition), zone()); |
| 3481 } | 3521 } |
| 3482 | 3522 |
| 3483 // For generators, allocate and yield an iterator on function entry. | 3523 // For generators, allocate and yield an iterator on function entry. |
| 3484 if (is_generator) { | 3524 if (is_generator) { |
| 3485 ZoneList<Expression*>* arguments = | 3525 ZoneList<Expression*>* arguments = |
| 3486 new(zone()) ZoneList<Expression*>(0, zone()); | 3526 new(zone()) ZoneList<Expression*>(0, zone()); |
| 3487 CallRuntime* allocation = factory()->NewCallRuntime( | 3527 CallRuntime* allocation = factory()->NewCallRuntime( |
| 3488 isolate()->factory()->empty_string(), | 3528 symbol_table_->empty_string(), |
| 3489 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), | 3529 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
| 3490 arguments, pos); | 3530 arguments, pos); |
| 3491 VariableProxy* init_proxy = factory()->NewVariableProxy( | 3531 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 3492 function_state_->generator_object_variable()); | 3532 function_state_->generator_object_variable()); |
| 3493 Assignment* assignment = factory()->NewAssignment( | 3533 Assignment* assignment = factory()->NewAssignment( |
| 3494 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3534 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 3495 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3535 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3496 function_state_->generator_object_variable()); | 3536 function_state_->generator_object_variable()); |
| 3497 Yield* yield = factory()->NewYield( | 3537 Yield* yield = factory()->NewYield( |
| 3498 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 3538 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 allow_harmony_numeric_literals()); | 3578 allow_harmony_numeric_literals()); |
| 3539 } | 3579 } |
| 3540 PreParser::PreParseResult result = | 3580 PreParser::PreParseResult result = |
| 3541 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3581 reusable_preparser_->PreParseLazyFunction(strict_mode(), |
| 3542 is_generator(), | 3582 is_generator(), |
| 3543 logger); | 3583 logger); |
| 3544 return result; | 3584 return result; |
| 3545 } | 3585 } |
| 3546 | 3586 |
| 3547 | 3587 |
| 3588 void Parser::CheckPendingError() { |
| 3589 if (has_pending_error_) { |
| 3590 MessageLocation location(script_, |
| 3591 pending_location_.beg_pos, |
| 3592 pending_location_.end_pos); |
| 3593 Factory* factory = isolate()->factory(); |
| 3594 bool has_arg = pending_arg_ != NULL || pending_char_arg_ != NULL; |
| 3595 Handle<FixedArray> elements = |
| 3596 factory->NewFixedArray(has_arg ? 1 : 0); |
| 3597 if (pending_arg_ != NULL) { |
| 3598 Handle<String> arg_string = pending_arg_->string(); |
| 3599 elements->set(0, *arg_string); |
| 3600 } else if (pending_char_arg_ != NULL) { |
| 3601 Handle<String> arg_string = |
| 3602 factory->NewStringFromUtf8(CStrVector(pending_char_arg_)) |
| 3603 .ToHandleChecked(); |
| 3604 elements->set(0, *arg_string); |
| 3605 } |
| 3606 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 3607 Handle<Object> result = pending_is_reference_error_ |
| 3608 ? factory->NewReferenceError(pending_message_, array) |
| 3609 : factory->NewSyntaxError(pending_message_, array); |
| 3610 isolate()->Throw(*result, &location); |
| 3611 } |
| 3612 } |
| 3613 |
| 3614 |
| 3548 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3615 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3549 // CallRuntime :: | 3616 // CallRuntime :: |
| 3550 // '%' Identifier Arguments | 3617 // '%' Identifier Arguments |
| 3551 | 3618 |
| 3552 int pos = peek_position(); | 3619 int pos = peek_position(); |
| 3553 Expect(Token::MOD, CHECK_OK); | 3620 Expect(Token::MOD, CHECK_OK); |
| 3554 // Allow "eval" or "arguments" for backward compatibility. | 3621 // Allow "eval" or "arguments" for backward compatibility. |
| 3555 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3622 ParserSymbolTable::Symbol* name = |
| 3623 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3556 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3624 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3557 | 3625 |
| 3558 if (extension_ != NULL) { | 3626 if (extension_ != NULL) { |
| 3559 // The extension structures are only accessible while parsing the | 3627 // The extension structures are only accessible while parsing the |
| 3560 // very first time not when reparsing because of lazy compilation. | 3628 // very first time not when reparsing because of lazy compilation. |
| 3561 scope_->DeclarationScope()->ForceEagerCompilation(); | 3629 scope_->DeclarationScope()->ForceEagerCompilation(); |
| 3562 } | 3630 } |
| 3563 | 3631 |
| 3564 const Runtime::Function* function = Runtime::FunctionForName(name); | 3632 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
| 3565 | 3633 |
| 3566 // Check for built-in IS_VAR macro. | 3634 // Check for built-in IS_VAR macro. |
| 3567 if (function != NULL && | 3635 if (function != NULL && |
| 3568 function->intrinsic_type == Runtime::RUNTIME && | 3636 function->intrinsic_type == Runtime::RUNTIME && |
| 3569 function->function_id == Runtime::kIS_VAR) { | 3637 function->function_id == Runtime::kIS_VAR) { |
| 3570 // %IS_VAR(x) evaluates to x if x is a variable, | 3638 // %IS_VAR(x) evaluates to x if x is a variable, |
| 3571 // leads to a parse error otherwise. Could be implemented as an | 3639 // leads to a parse error otherwise. Could be implemented as an |
| 3572 // inline function %_IS_VAR(x) to eliminate this special case. | 3640 // inline function %_IS_VAR(x) to eliminate this special case. |
| 3573 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | 3641 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
| 3574 return args->at(0); | 3642 return args->at(0); |
| 3575 } else { | 3643 } else { |
| 3576 ReportMessage("not_isvar"); | 3644 ReportMessage("not_isvar"); |
| 3577 *ok = false; | 3645 *ok = false; |
| 3578 return NULL; | 3646 return NULL; |
| 3579 } | 3647 } |
| 3580 } | 3648 } |
| 3581 | 3649 |
| 3582 // Check that the expected number of arguments are being passed. | 3650 // Check that the expected number of arguments are being passed. |
| 3583 if (function != NULL && | 3651 if (function != NULL && |
| 3584 function->nargs != -1 && | 3652 function->nargs != -1 && |
| 3585 function->nargs != args->length()) { | 3653 function->nargs != args->length()) { |
| 3586 ReportMessage("illegal_access"); | 3654 ReportMessage("illegal_access"); |
| 3587 *ok = false; | 3655 *ok = false; |
| 3588 return NULL; | 3656 return NULL; |
| 3589 } | 3657 } |
| 3590 | 3658 |
| 3591 // Check that the function is defined if it's an inline runtime call. | 3659 // Check that the function is defined if it's an inline runtime call. |
| 3592 if (function == NULL && name->Get(0) == '_') { | 3660 if (function == NULL && name->literal_bytes.at(0) == '_') { |
| 3593 ParserTraits::ReportMessage("not_defined", name); | 3661 ParserTraits::ReportMessage("not_defined", name); |
| 3594 *ok = false; | 3662 *ok = false; |
| 3595 return NULL; | 3663 return NULL; |
| 3596 } | 3664 } |
| 3597 | 3665 |
| 3598 // We have a valid intrinsics call or a call to a builtin. | 3666 // We have a valid intrinsics call or a call to a builtin. |
| 3599 return factory()->NewCallRuntime(name, function, args, pos); | 3667 return factory()->NewCallRuntime(name, function, args, pos); |
| 3600 } | 3668 } |
| 3601 | 3669 |
| 3602 | 3670 |
| 3603 Literal* Parser::GetLiteralUndefined(int position) { | 3671 Literal* Parser::GetLiteralUndefined(int position) { |
| 3604 return factory()->NewLiteral( | 3672 return factory()->NewLiteral( |
| 3605 isolate()->factory()->undefined_value(), position); | 3673 isolate()->factory()->undefined_value(), position); |
| 3606 } | 3674 } |
| 3607 | 3675 |
| 3608 | 3676 |
| 3609 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3677 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 3610 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3678 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 3611 if (decl != NULL) { | 3679 if (decl != NULL) { |
| 3612 // In harmony mode we treat conflicting variable bindinds as early | 3680 // In harmony mode we treat conflicting variable bindinds as early |
| 3613 // errors. See ES5 16 for a definition of early errors. | 3681 // errors. See ES5 16 for a definition of early errors. |
| 3614 Handle<String> name = decl->proxy()->name(); | 3682 ParserSymbolTable::Symbol* name = decl->proxy()->raw_name(); |
| 3615 int position = decl->proxy()->position(); | 3683 int position = decl->proxy()->position(); |
| 3616 Scanner::Location location = position == RelocInfo::kNoPosition | 3684 Scanner::Location location = position == RelocInfo::kNoPosition |
| 3617 ? Scanner::Location::invalid() | 3685 ? Scanner::Location::invalid() |
| 3618 : Scanner::Location(position, position + 1); | 3686 : Scanner::Location(position, position + 1); |
| 3619 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 3687 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
| 3620 *ok = false; | 3688 *ok = false; |
| 3621 } | 3689 } |
| 3622 } | 3690 } |
| 3623 | 3691 |
| 3624 | 3692 |
| 3625 // ---------------------------------------------------------------------------- | 3693 // ---------------------------------------------------------------------------- |
| 3626 // Parser support | 3694 // Parser support |
| 3627 | 3695 |
| 3628 | 3696 |
| 3629 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3697 bool Parser::TargetStackContainsLabel(ParserSymbolTable::Symbol* label) { |
| 3630 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3698 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3631 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3699 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3632 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 3700 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 3633 return true; | 3701 return true; |
| 3634 } | 3702 } |
| 3635 return false; | 3703 return false; |
| 3636 } | 3704 } |
| 3637 | 3705 |
| 3638 | 3706 |
| 3639 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { | 3707 BreakableStatement* Parser::LookupBreakTarget(ParserSymbolTable::Symbol* label, |
| 3640 bool anonymous = label.is_null(); | 3708 bool* ok) { |
| 3709 bool anonymous = label == NULL; |
| 3641 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3710 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3642 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3711 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3643 if (stat == NULL) continue; | 3712 if (stat == NULL) continue; |
| 3644 if ((anonymous && stat->is_target_for_anonymous()) || | 3713 if ((anonymous && stat->is_target_for_anonymous()) || |
| 3645 (!anonymous && ContainsLabel(stat->labels(), label))) { | 3714 (!anonymous && ContainsLabel(stat->labels(), label))) { |
| 3646 RegisterTargetUse(stat->break_target(), t->previous()); | 3715 RegisterTargetUse(stat->break_target(), t->previous()); |
| 3647 return stat; | 3716 return stat; |
| 3648 } | 3717 } |
| 3649 } | 3718 } |
| 3650 return NULL; | 3719 return NULL; |
| 3651 } | 3720 } |
| 3652 | 3721 |
| 3653 | 3722 |
| 3654 IterationStatement* Parser::LookupContinueTarget(Handle<String> label, | 3723 IterationStatement* Parser::LookupContinueTarget( |
| 3655 bool* ok) { | 3724 ParserSymbolTable::Symbol* label, bool* ok) { |
| 3656 bool anonymous = label.is_null(); | 3725 bool anonymous = label == NULL; |
| 3657 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3726 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3658 IterationStatement* stat = t->node()->AsIterationStatement(); | 3727 IterationStatement* stat = t->node()->AsIterationStatement(); |
| 3659 if (stat == NULL) continue; | 3728 if (stat == NULL) continue; |
| 3660 | 3729 |
| 3661 ASSERT(stat->is_target_for_anonymous()); | 3730 ASSERT(stat->is_target_for_anonymous()); |
| 3662 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3731 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 3663 RegisterTargetUse(stat->continue_target(), t->previous()); | 3732 RegisterTargetUse(stat->continue_target(), t->previous()); |
| 3664 return stat; | 3733 return stat; |
| 3665 } | 3734 } |
| 3666 } | 3735 } |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4569 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 4638 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 4570 result->contains_anchor = parser.contains_anchor(); | 4639 result->contains_anchor = parser.contains_anchor(); |
| 4571 result->capture_count = capture_count; | 4640 result->capture_count = capture_count; |
| 4572 } | 4641 } |
| 4573 return !parser.failed(); | 4642 return !parser.failed(); |
| 4574 } | 4643 } |
| 4575 | 4644 |
| 4576 | 4645 |
| 4577 bool Parser::Parse() { | 4646 bool Parser::Parse() { |
| 4578 ASSERT(info()->function() == NULL); | 4647 ASSERT(info()->function() == NULL); |
| 4648 ASSERT(info()->symbol_table() == NULL); |
| 4579 FunctionLiteral* result = NULL; | 4649 FunctionLiteral* result = NULL; |
| 4650 symbol_table_ = new ParserSymbolTable(); |
| 4651 if (allow_natives_syntax() || extension_ != NULL) { |
| 4652 symbol_table_->AlwaysInternalize(isolate()); |
| 4653 } |
| 4654 |
| 4580 if (info()->is_lazy()) { | 4655 if (info()->is_lazy()) { |
| 4581 ASSERT(!info()->is_eval()); | 4656 ASSERT(!info()->is_eval()); |
| 4582 if (info()->shared_info()->is_function()) { | 4657 if (info()->shared_info()->is_function()) { |
| 4583 result = ParseLazy(); | 4658 result = ParseLazy(); |
| 4584 } else { | 4659 } else { |
| 4585 result = ParseProgram(); | 4660 result = ParseProgram(); |
| 4586 } | 4661 } |
| 4587 } else { | 4662 } else { |
| 4588 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4663 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
| 4589 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && | 4664 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
| 4590 (*info()->cached_data())->has_error()) { | 4665 (*info()->cached_data())->has_error()) { |
| 4591 ScriptData* cached_data = *(info()->cached_data()); | 4666 ScriptData* cached_data = *(info()->cached_data()); |
| 4592 Scanner::Location loc = cached_data->MessageLocation(); | 4667 Scanner::Location loc = cached_data->MessageLocation(); |
| 4593 const char* message = cached_data->BuildMessage(); | 4668 const char* message = cached_data->BuildMessage(); |
| 4594 const char* arg = cached_data->BuildArg(); | 4669 const char* arg = cached_data->BuildArg(); |
| 4595 ParserTraits::ReportMessageAt(loc, message, arg, | 4670 ParserTraits::ReportMessageAt(loc, message, arg, |
| 4596 cached_data->IsReferenceError()); | 4671 cached_data->IsReferenceError()); |
| 4597 DeleteArray(message); | 4672 DeleteArray(message); |
| 4598 DeleteArray(arg); | 4673 DeleteArray(arg); |
| 4599 ASSERT(info()->isolate()->has_pending_exception()); | 4674 ASSERT(info()->isolate()->has_pending_exception()); |
| 4600 } else { | 4675 } else { |
| 4601 result = ParseProgram(); | 4676 result = ParseProgram(); |
| 4602 } | 4677 } |
| 4603 } | 4678 } |
| 4604 info()->SetFunction(result); | 4679 info()->SetFunction(result); |
| 4680 // info takes ownership of symbol_table_. |
| 4681 info()->SetSymbolTable(symbol_table_); |
| 4682 symbol_table_ = NULL; |
| 4605 return (result != NULL); | 4683 return (result != NULL); |
| 4606 } | 4684 } |
| 4607 | 4685 |
| 4608 } } // namespace v8::internal | 4686 } } // namespace v8::internal |
| OLD | NEW |