| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/char-predicates-inl.h" | 10 #include "src/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(ast_value_factory_); |
| 330 Scope* result = |
| 331 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); |
| 330 result->Initialize(); | 332 result->Initialize(); |
| 331 return result; | 333 return result; |
| 332 } | 334 } |
| 333 | 335 |
| 334 | 336 |
| 335 // ---------------------------------------------------------------------------- | 337 // ---------------------------------------------------------------------------- |
| 336 // Target is a support class to facilitate manipulation of the | 338 // Target is a support class to facilitate manipulation of the |
| 337 // Parser's target_stack_ (the stack of potential 'break' and | 339 // Parser's target_stack_ (the stack of potential 'break' and |
| 338 // 'continue' statement targets). Upon construction, a new target is | 340 // 'continue' statement targets). Upon construction, a new target is |
| 339 // added; it is removed upon destruction. | 341 // added; it is removed upon destruction. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 394 |
| 393 #define CHECK_FAILED /**/); \ | 395 #define CHECK_FAILED /**/); \ |
| 394 if (failed_) return NULL; \ | 396 if (failed_) return NULL; \ |
| 395 ((void)0 | 397 ((void)0 |
| 396 #define DUMMY ) // to make indentation work | 398 #define DUMMY ) // to make indentation work |
| 397 #undef DUMMY | 399 #undef DUMMY |
| 398 | 400 |
| 399 // ---------------------------------------------------------------------------- | 401 // ---------------------------------------------------------------------------- |
| 400 // Implementation of Parser | 402 // Implementation of Parser |
| 401 | 403 |
| 402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 404 bool ParserTraits::IsEvalOrArguments(const AstString* identifier) const { |
| 403 Factory* factory = parser_->isolate()->factory(); | 405 return identifier == parser_->ast_value_factory_->eval_string() || |
| 404 return identifier.is_identical_to(factory->eval_string()) | 406 identifier == parser_->ast_value_factory_->arguments_string(); |
| 405 || identifier.is_identical_to(factory->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( |
| 430 parser_->isolate()->factory()->anonymous_function_string()); | 431 parser_->ast_value_factory_->anonymous_function_string()); |
| 431 } | 432 } |
| 432 } | 433 } |
| 433 | 434 |
| 434 | 435 |
| 435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 436 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 436 Expression* right) { | 437 Expression* right) { |
| 437 ASSERT(left != NULL); | 438 ASSERT(left != NULL); |
| 438 if (left->AsProperty() != NULL && | 439 if (left->AsProperty() != NULL && |
| 439 right->AsFunctionLiteral() != NULL) { | 440 right->AsFunctionLiteral() != NULL) { |
| 440 right->AsFunctionLiteral()->set_pretenure(); | 441 right->AsFunctionLiteral()->set_pretenure(); |
| 441 } | 442 } |
| 442 } | 443 } |
| 443 | 444 |
| 444 | 445 |
| 445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 446 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
| 446 Scope* scope) { | 447 Scope* scope) { |
| 447 VariableProxy* callee = expression->AsVariableProxy(); | 448 VariableProxy* callee = expression->AsVariableProxy(); |
| 448 if (callee != NULL && | 449 if (callee != NULL && |
| 449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) { | 450 callee->raw_name() == parser_->ast_value_factory_->eval_string()) { |
| 450 scope->DeclarationScope()->RecordEvalCall(); | 451 scope->DeclarationScope()->RecordEvalCall(); |
| 451 } | 452 } |
| 452 } | 453 } |
| 453 | 454 |
| 454 | 455 |
| 455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 456 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 456 VariableProxy* proxy = expression != NULL | 457 VariableProxy* proxy = expression != NULL |
| 457 ? expression->AsVariableProxy() | 458 ? expression->AsVariableProxy() |
| 458 : NULL; | 459 : NULL; |
| 459 if (proxy != NULL) proxy->MarkAsLValue(); | 460 if (proxy != NULL) proxy->MarkAsLValue(); |
| 460 return expression; | 461 return expression; |
| 461 } | 462 } |
| 462 | 463 |
| 463 | 464 |
| 464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 465 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
| 465 Expression** x, Expression* y, Token::Value op, int pos, | 466 Expression** x, Expression* y, Token::Value op, int pos, |
| 466 AstNodeFactory<AstConstructionVisitor>* factory) { | 467 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && | 468 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && |
| 468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 469 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { |
| 469 double x_val = (*x)->AsLiteral()->value()->Number(); | 470 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); |
| 470 double y_val = y->AsLiteral()->value()->Number(); | 471 double y_val = y->AsLiteral()->raw_value()->AsNumber(); |
| 471 switch (op) { | 472 switch (op) { |
| 472 case Token::ADD: | 473 case Token::ADD: |
| 473 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 474 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| 474 return true; | 475 return true; |
| 475 case Token::SUB: | 476 case Token::SUB: |
| 476 *x = factory->NewNumberLiteral(x_val - y_val, pos); | 477 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
| 477 return true; | 478 return true; |
| 478 case Token::MUL: | 479 case Token::MUL: |
| 479 *x = factory->NewNumberLiteral(x_val * y_val, pos); | 480 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
| 480 return true; | 481 return true; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 } | 520 } |
| 520 return false; | 521 return false; |
| 521 } | 522 } |
| 522 | 523 |
| 523 | 524 |
| 524 Expression* ParserTraits::BuildUnaryExpression( | 525 Expression* ParserTraits::BuildUnaryExpression( |
| 525 Expression* expression, Token::Value op, int pos, | 526 Expression* expression, Token::Value op, int pos, |
| 526 AstNodeFactory<AstConstructionVisitor>* factory) { | 527 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 527 ASSERT(expression != NULL); | 528 ASSERT(expression != NULL); |
| 528 if (expression->IsLiteral()) { | 529 if (expression->IsLiteral()) { |
| 529 Handle<Object> literal = expression->AsLiteral()->value(); | 530 const AstValue* literal = expression->AsLiteral()->raw_value(); |
| 530 if (op == Token::NOT) { | 531 if (op == Token::NOT) { |
| 531 // Convert the literal to a boolean condition and negate it. | 532 // Convert the literal to a boolean condition and negate it. |
| 532 bool condition = literal->BooleanValue(); | 533 bool condition = literal->BooleanValue(); |
| 533 Handle<Object> result = | 534 return factory->NewBooleanLiteral(!condition, pos); |
| 534 parser_->isolate()->factory()->ToBoolean(!condition); | |
| 535 return factory->NewLiteral(result, pos); | |
| 536 } else if (literal->IsNumber()) { | 535 } else if (literal->IsNumber()) { |
| 537 // Compute some expressions involving only number literals. | 536 // Compute some expressions involving only number literals. |
| 538 double value = literal->Number(); | 537 double value = literal->AsNumber(); |
| 539 switch (op) { | 538 switch (op) { |
| 540 case Token::ADD: | 539 case Token::ADD: |
| 541 return expression; | 540 return expression; |
| 542 case Token::SUB: | 541 case Token::SUB: |
| 543 return factory->NewNumberLiteral(-value, pos); | 542 return factory->NewNumberLiteral(-value, pos); |
| 544 case Token::BIT_NOT: | 543 case Token::BIT_NOT: |
| 545 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); | 544 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 546 default: | 545 default: |
| 547 break; | 546 break; |
| 548 } | 547 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 562 if (op == Token::BIT_NOT) { | 561 if (op == Token::BIT_NOT) { |
| 563 return factory->NewBinaryOperation( | 562 return factory->NewBinaryOperation( |
| 564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 563 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
| 565 } | 564 } |
| 566 return factory->NewUnaryOperation(op, expression, pos); | 565 return factory->NewUnaryOperation(op, expression, pos); |
| 567 } | 566 } |
| 568 | 567 |
| 569 | 568 |
| 570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { | 569 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
| 571 return NewThrowError( | 570 return NewThrowError( |
| 572 parser_->isolate()->factory()->MakeReferenceError_string(), | 571 parser_->ast_value_factory_->make_reference_error_string(), message, NULL, |
| 573 message, HandleVector<Object>(NULL, 0), pos); | 572 pos); |
| 574 } | 573 } |
| 575 | 574 |
| 576 | 575 |
| 577 Expression* ParserTraits::NewThrowSyntaxError( | 576 Expression* ParserTraits::NewThrowSyntaxError( |
| 578 const char* message, Handle<Object> arg, int pos) { | 577 const char* message, const AstString* arg, int pos) { |
| 579 int argc = arg.is_null() ? 0 : 1; | 578 return NewThrowError(parser_->ast_value_factory_->make_syntax_error_string(), |
| 580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 579 message, arg, pos); |
| 581 return NewThrowError( | |
| 582 parser_->isolate()->factory()->MakeSyntaxError_string(), | |
| 583 message, arguments, pos); | |
| 584 } | 580 } |
| 585 | 581 |
| 586 | 582 |
| 587 Expression* ParserTraits::NewThrowTypeError( | 583 Expression* ParserTraits::NewThrowTypeError( |
| 588 const char* message, Handle<Object> arg, int pos) { | 584 const char* message, const AstString* arg, int pos) { |
| 589 int argc = arg.is_null() ? 0 : 1; | 585 return NewThrowError(parser_->ast_value_factory_->make_type_error_string(), |
| 590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); | 586 message, arg, pos); |
| 591 return NewThrowError( | |
| 592 parser_->isolate()->factory()->MakeTypeError_string(), | |
| 593 message, arguments, pos); | |
| 594 } | 587 } |
| 595 | 588 |
| 596 | 589 |
| 597 Expression* ParserTraits::NewThrowError( | 590 Expression* ParserTraits::NewThrowError( |
| 598 Handle<String> constructor, const char* message, | 591 const AstString* constructor, const char* message, |
| 599 Vector<Handle<Object> > arguments, int pos) { | 592 const AstString* arg, int pos) { |
| 600 Zone* zone = parser_->zone(); | 593 Zone* zone = parser_->zone(); |
| 601 Factory* factory = parser_->isolate()->factory(); | 594 int argc = arg != NULL ? 1 : 0; |
| 602 int argc = arguments.length(); | 595 const AstString* type = |
| 603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); | 596 parser_->ast_value_factory_->GetOneByteString(Vector<const uint8_t>( |
| 604 for (int i = 0; i < argc; i++) { | 597 reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
| 605 Handle<Object> element = arguments[i]; | 598 ZoneList<const AstString*>* array = |
| 606 if (!element.is_null()) { | 599 new (zone) ZoneList<const AstString*>(argc, zone); |
| 607 elements->set(i, *element); | 600 if (arg != NULL) { |
| 608 } | 601 array->Add(arg, zone); |
| 609 } | 602 } |
| 610 Handle<JSArray> array = | 603 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
| 611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); | 604 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone); |
| 612 | 605 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone); |
| 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 = | 606 CallRuntime* call_constructor = |
| 618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | 607 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
| 619 return parser_->factory()->NewThrow(call_constructor, pos); | 608 return parser_->factory()->NewThrow(call_constructor, pos); |
| 620 } | 609 } |
| 621 | 610 |
| 622 | 611 |
| 623 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 612 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 624 const char* message, | 613 const char* message, |
| 625 const char* arg, | 614 const char* arg, |
| 626 bool is_reference_error) { | 615 bool is_reference_error) { |
| 627 if (parser_->stack_overflow()) { | 616 if (parser_->stack_overflow()) { |
| 628 // Suppress the error message (syntax error or such) in the presence of a | 617 // 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 | 618 // stack overflow. The isolate allows only one pending exception at at time |
| 630 // and we want to report the stack overflow later. | 619 // and we want to report the stack overflow later. |
| 631 return; | 620 return; |
| 632 } | 621 } |
| 633 parser_->has_pending_error_ = true; | 622 parser_->has_pending_error_ = true; |
| 634 parser_->pending_error_location_ = source_location; | 623 parser_->pending_error_location_ = source_location; |
| 635 parser_->pending_error_message_ = message; | 624 parser_->pending_error_message_ = message; |
| 636 parser_->pending_error_char_arg_ = arg; | 625 parser_->pending_error_char_arg_ = arg; |
| 637 parser_->pending_error_arg_ = Handle<String>(); | 626 parser_->pending_error_arg_ = NULL; |
| 638 parser_->pending_error_is_reference_error_ = is_reference_error; | 627 parser_->pending_error_is_reference_error_ = is_reference_error; |
| 639 } | 628 } |
| 640 | 629 |
| 641 | 630 |
| 642 void ParserTraits::ReportMessage(const char* message, | 631 void ParserTraits::ReportMessage(const char* message, |
| 643 MaybeHandle<String> arg, | 632 const char* arg, |
| 644 bool is_reference_error) { | 633 bool is_reference_error) { |
| 645 Scanner::Location source_location = parser_->scanner()->location(); | 634 Scanner::Location source_location = parser_->scanner()->location(); |
| 646 ReportMessageAt(source_location, message, arg, is_reference_error); | 635 ReportMessageAt(source_location, message, arg, is_reference_error); |
| 636 } |
| 637 |
| 638 |
| 639 void ParserTraits::ReportMessage(const char* message, |
| 640 const AstString* arg, |
| 641 bool is_reference_error) { |
| 642 Scanner::Location source_location = parser_->scanner()->location(); |
| 643 ReportMessageAt(source_location, message, arg, is_reference_error); |
| 647 } | 644 } |
| 648 | 645 |
| 649 | 646 |
| 650 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 647 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 651 const char* message, | 648 const char* message, |
| 652 MaybeHandle<String> arg, | 649 const AstString* arg, |
| 653 bool is_reference_error) { | 650 bool is_reference_error) { |
| 654 if (parser_->stack_overflow()) { | 651 if (parser_->stack_overflow()) { |
| 655 // Suppress the error message (syntax error or such) in the presence of a | 652 // Suppress the error message (syntax error or such) in the presence of a |
| 656 // stack overflow. The isolate allows only one pending exception at at time | 653 // stack overflow. The isolate allows only one pending exception at at time |
| 657 // and we want to report the stack overflow later. | 654 // and we want to report the stack overflow later. |
| 658 return; | 655 return; |
| 659 } | 656 } |
| 660 parser_->has_pending_error_ = true; | 657 parser_->has_pending_error_ = true; |
| 661 parser_->pending_error_location_ = source_location; | 658 parser_->pending_error_location_ = source_location; |
| 662 parser_->pending_error_message_ = message; | 659 parser_->pending_error_message_ = message; |
| 663 parser_->pending_error_char_arg_ = NULL; | 660 parser_->pending_error_char_arg_ = NULL; |
| 664 parser_->pending_error_arg_ = arg; | 661 parser_->pending_error_arg_ = arg; |
| 665 parser_->pending_error_is_reference_error_ = is_reference_error; | 662 parser_->pending_error_is_reference_error_ = is_reference_error; |
| 666 } | 663 } |
| 667 | 664 |
| 668 | 665 |
| 669 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 666 const AstString* ParserTraits::GetSymbol(Scanner* scanner) { |
| 670 Handle<String> result = | 667 const AstString* result = |
| 671 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); | 668 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); |
| 672 ASSERT(!result.is_null()); | 669 ASSERT(result != NULL); |
| 673 return result; | 670 return result; |
| 674 } | 671 } |
| 675 | 672 |
| 676 | 673 |
| 677 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 674 const AstString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
| 678 PretenureFlag tenured) { | 675 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); |
| 679 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | |
| 680 } | 676 } |
| 681 | 677 |
| 682 | 678 |
| 683 Expression* ParserTraits::ThisExpression( | 679 Expression* ParserTraits::ThisExpression( |
| 684 Scope* scope, | 680 Scope* scope, |
| 685 AstNodeFactory<AstConstructionVisitor>* factory) { | 681 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 686 return factory->NewVariableProxy(scope->receiver()); | 682 return factory->NewVariableProxy(scope->receiver()); |
| 687 } | 683 } |
| 688 | 684 |
| 689 | 685 |
| 690 Literal* ParserTraits::ExpressionFromLiteral( | 686 Literal* ParserTraits::ExpressionFromLiteral( |
| 691 Token::Value token, int pos, | 687 Token::Value token, int pos, |
| 692 Scanner* scanner, | 688 Scanner* scanner, |
| 693 AstNodeFactory<AstConstructionVisitor>* factory) { | 689 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 694 Factory* isolate_factory = parser_->isolate()->factory(); | |
| 695 switch (token) { | 690 switch (token) { |
| 696 case Token::NULL_LITERAL: | 691 case Token::NULL_LITERAL: |
| 697 return factory->NewLiteral(isolate_factory->null_value(), pos); | 692 return factory->NewNullLiteral(pos); |
| 698 case Token::TRUE_LITERAL: | 693 case Token::TRUE_LITERAL: |
| 699 return factory->NewLiteral(isolate_factory->true_value(), pos); | 694 return factory->NewBooleanLiteral(true, pos); |
| 700 case Token::FALSE_LITERAL: | 695 case Token::FALSE_LITERAL: |
| 701 return factory->NewLiteral(isolate_factory->false_value(), pos); | 696 return factory->NewBooleanLiteral(false, pos); |
| 702 case Token::NUMBER: { | 697 case Token::NUMBER: { |
| 703 double value = scanner->DoubleValue(); | 698 double value = scanner->DoubleValue(); |
| 704 return factory->NewNumberLiteral(value, pos); | 699 return factory->NewNumberLiteral(value, pos); |
| 705 } | 700 } |
| 706 default: | 701 default: |
| 707 ASSERT(false); | 702 ASSERT(false); |
| 708 } | 703 } |
| 709 return NULL; | 704 return NULL; |
| 710 } | 705 } |
| 711 | 706 |
| 712 | 707 |
| 713 Expression* ParserTraits::ExpressionFromIdentifier( | 708 Expression* ParserTraits::ExpressionFromIdentifier( |
| 714 Handle<String> name, int pos, Scope* scope, | 709 const AstString* name, int pos, Scope* scope, |
| 715 AstNodeFactory<AstConstructionVisitor>* factory) { | 710 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 716 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 711 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 717 // The name may refer to a module instance object, so its type is unknown. | 712 // The name may refer to a module instance object, so its type is unknown. |
| 718 #ifdef DEBUG | 713 #ifdef DEBUG |
| 719 if (FLAG_print_interface_details) | 714 if (FLAG_print_interface_details) |
| 720 PrintF("# Variable %s ", name->ToAsciiArray()); | 715 PrintF("# Variable %.*s ", name->length(), name->raw_data()); |
| 721 #endif | 716 #endif |
| 722 Interface* interface = Interface::NewUnknown(parser_->zone()); | 717 Interface* interface = Interface::NewUnknown(parser_->zone()); |
| 723 return scope->NewUnresolved(factory, name, interface, pos); | 718 return scope->NewUnresolved(factory, name, interface, pos); |
| 724 } | 719 } |
| 725 | 720 |
| 726 | 721 |
| 727 Expression* ParserTraits::ExpressionFromString( | 722 Expression* ParserTraits::ExpressionFromString( |
| 728 int pos, Scanner* scanner, | 723 int pos, Scanner* scanner, |
| 729 AstNodeFactory<AstConstructionVisitor>* factory) { | 724 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 730 Handle<String> symbol = GetSymbol(scanner); | 725 const AstString* symbol = GetSymbol(scanner); |
| 731 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 726 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 732 return factory->NewLiteral(symbol, pos); | 727 return factory->NewStringLiteral(symbol, pos); |
| 733 } | 728 } |
| 734 | 729 |
| 735 | 730 |
| 736 Literal* ParserTraits::GetLiteralTheHole( | 731 Literal* ParserTraits::GetLiteralTheHole( |
| 737 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 732 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 738 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 733 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition); |
| 739 RelocInfo::kNoPosition); | |
| 740 } | 734 } |
| 741 | 735 |
| 742 | 736 |
| 743 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 737 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 744 return parser_->ParseV8Intrinsic(ok); | 738 return parser_->ParseV8Intrinsic(ok); |
| 745 } | 739 } |
| 746 | 740 |
| 747 | 741 |
| 748 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 742 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| 749 Handle<String> name, | 743 const AstString* name, |
| 750 Scanner::Location function_name_location, | 744 Scanner::Location function_name_location, |
| 751 bool name_is_strict_reserved, | 745 bool name_is_strict_reserved, |
| 752 bool is_generator, | 746 bool is_generator, |
| 753 int function_token_position, | 747 int function_token_position, |
| 754 FunctionLiteral::FunctionType type, | 748 FunctionLiteral::FunctionType type, |
| 755 bool* ok) { | 749 bool* ok) { |
| 756 return parser_->ParseFunctionLiteral(name, function_name_location, | 750 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 757 name_is_strict_reserved, is_generator, | 751 name_is_strict_reserved, is_generator, |
| 758 function_token_position, type, ok); | 752 function_token_position, type, ok); |
| 759 } | 753 } |
| 760 | 754 |
| 761 | 755 |
| 762 Parser::Parser(CompilationInfo* info) | 756 Parser::Parser(CompilationInfo* info) |
| 763 : ParserBase<ParserTraits>(&scanner_, | 757 : ParserBase<ParserTraits>(&scanner_, |
| 764 info->isolate()->stack_guard()->real_climit(), | 758 info->isolate()->stack_guard()->real_climit(), |
| 765 info->extension(), | 759 info->extension(), |
| 766 NULL, | 760 NULL, |
| 767 info->zone(), | 761 info->zone(), |
| 768 this), | 762 this), |
| 769 isolate_(info->isolate()), | 763 isolate_(info->isolate()), |
| 770 script_(info->script()), | 764 script_(info->script()), |
| 771 scanner_(isolate_->unicode_cache()), | 765 scanner_(isolate_->unicode_cache()), |
| 772 reusable_preparser_(NULL), | 766 reusable_preparser_(NULL), |
| 773 original_scope_(NULL), | 767 original_scope_(NULL), |
| 774 target_stack_(NULL), | 768 target_stack_(NULL), |
| 775 cached_data_(NULL), | 769 cached_data_(NULL), |
| 776 cached_data_mode_(NO_CACHED_DATA), | 770 cached_data_mode_(NO_CACHED_DATA), |
| 771 ast_value_factory_(NULL), |
| 777 info_(info), | 772 info_(info), |
| 778 has_pending_error_(false), | 773 has_pending_error_(false), |
| 779 pending_error_message_(NULL), | 774 pending_error_message_(NULL), |
| 775 pending_error_arg_(NULL), |
| 780 pending_error_char_arg_(NULL) { | 776 pending_error_char_arg_(NULL) { |
| 781 ASSERT(!script_.is_null()); | 777 ASSERT(!script_.is_null()); |
| 782 isolate_->set_ast_node_id(0); | 778 isolate_->set_ast_node_id(0); |
| 783 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 779 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 784 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 780 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 785 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 781 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 786 set_allow_lazy(false); // Must be explicitly enabled. | 782 set_allow_lazy(false); // Must be explicitly enabled. |
| 787 set_allow_generators(FLAG_harmony_generators); | 783 set_allow_generators(FLAG_harmony_generators); |
| 788 set_allow_for_of(FLAG_harmony_iteration); | 784 set_allow_for_of(FLAG_harmony_iteration); |
| 789 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 785 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 790 } | 786 } |
| 791 | 787 |
| 792 | 788 |
| 793 FunctionLiteral* Parser::ParseProgram() { | 789 FunctionLiteral* Parser::ParseProgram() { |
| 794 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 790 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 795 // see comment for HistogramTimerScope class. | 791 // see comment for HistogramTimerScope class. |
| 796 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 792 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 797 Handle<String> source(String::cast(script_->source())); | 793 Handle<String> source(String::cast(script_->source())); |
| 798 isolate()->counters()->total_parse_size()->Increment(source->length()); | 794 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 799 ElapsedTimer timer; | 795 ElapsedTimer timer; |
| 800 if (FLAG_trace_parse) { | 796 if (FLAG_trace_parse) { |
| 801 timer.Start(); | 797 timer.Start(); |
| 802 } | 798 } |
| 803 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 799 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 804 | 800 |
| 805 // Initialize parser state. | 801 // Initialize parser state. |
| 806 CompleteParserRecorder recorder; | 802 CompleteParserRecorder recorder; |
| 807 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 803 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 808 log_ = &recorder; | 804 log_ = &recorder; |
| 809 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 805 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 810 (*cached_data_)->Initialize(); | 806 (*cached_data_)->Initialize(); |
| 811 } | 807 } |
| 812 | 808 |
| 813 source = String::Flatten(source); | 809 source = String::Flatten(source); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 } | 844 } |
| 849 return result; | 845 return result; |
| 850 } | 846 } |
| 851 | 847 |
| 852 | 848 |
| 853 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 849 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 854 Handle<String> source) { | 850 Handle<String> source) { |
| 855 ASSERT(scope_ == NULL); | 851 ASSERT(scope_ == NULL); |
| 856 ASSERT(target_stack_ == NULL); | 852 ASSERT(target_stack_ == NULL); |
| 857 | 853 |
| 858 Handle<String> no_name = isolate()->factory()->empty_string(); | |
| 859 | |
| 860 FunctionLiteral* result = NULL; | 854 FunctionLiteral* result = NULL; |
| 861 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 855 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 862 info->SetGlobalScope(scope); | 856 info->SetGlobalScope(scope); |
| 863 if (!info->context().is_null()) { | 857 if (!info->context().is_null()) { |
| 864 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 858 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 859 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 860 // means the Parser cannot operate independent of the V8 heap. Tell the |
| 861 // string table to internalize strings and values right after they're |
| 862 // created. |
| 863 ast_value_factory_->Internalize(isolate()); |
| 865 } | 864 } |
| 866 original_scope_ = scope; | 865 original_scope_ = scope; |
| 867 if (info->is_eval()) { | 866 if (info->is_eval()) { |
| 868 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { | 867 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
| 869 scope = NewScope(scope, EVAL_SCOPE); | 868 scope = NewScope(scope, EVAL_SCOPE); |
| 870 } | 869 } |
| 871 } else if (info->is_global()) { | 870 } else if (info->is_global()) { |
| 872 scope = NewScope(scope, GLOBAL_SCOPE); | 871 scope = NewScope(scope, GLOBAL_SCOPE); |
| 873 } | 872 } |
| 874 scope->set_start_position(0); | 873 scope->set_start_position(0); |
| 875 scope->set_end_position(source->length()); | 874 scope->set_end_position(source->length()); |
| 876 | 875 |
| 877 // Compute the parsing mode. | 876 // Compute the parsing mode. |
| 878 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 877 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 879 if (allow_natives_syntax() || | 878 if (allow_natives_syntax() || |
| 880 extension_ != NULL || | 879 extension_ != NULL || |
| 881 scope->is_eval_scope()) { | 880 scope->is_eval_scope()) { |
| 882 mode = PARSE_EAGERLY; | 881 mode = PARSE_EAGERLY; |
| 883 } | 882 } |
| 884 ParsingModeScope parsing_mode(this, mode); | 883 ParsingModeScope parsing_mode(this, mode); |
| 885 | 884 |
| 886 // Enters 'scope'. | 885 // Enters 'scope'. |
| 887 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 886 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 887 ast_value_factory_); |
| 888 | 888 |
| 889 scope_->SetStrictMode(info->strict_mode()); | 889 scope_->SetStrictMode(info->strict_mode()); |
| 890 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 890 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 891 bool ok = true; | 891 bool ok = true; |
| 892 int beg_pos = scanner()->location().beg_pos; | 892 int beg_pos = scanner()->location().beg_pos; |
| 893 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 893 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 894 if (ok && strict_mode() == STRICT) { | 894 if (ok && strict_mode() == STRICT) { |
| 895 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 895 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 896 } | 896 } |
| 897 | 897 |
| 898 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 898 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 899 CheckConflictingVarDeclarations(scope_, &ok); | 899 CheckConflictingVarDeclarations(scope_, &ok); |
| 900 } | 900 } |
| 901 | 901 |
| 902 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 902 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 903 if (body->length() != 1 || | 903 if (body->length() != 1 || |
| 904 !body->at(0)->IsExpressionStatement() || | 904 !body->at(0)->IsExpressionStatement() || |
| 905 !body->at(0)->AsExpressionStatement()-> | 905 !body->at(0)->AsExpressionStatement()-> |
| 906 expression()->IsFunctionLiteral()) { | 906 expression()->IsFunctionLiteral()) { |
| 907 ReportMessage("single_function_literal"); | 907 ReportMessage("single_function_literal"); |
| 908 ok = false; | 908 ok = false; |
| 909 } | 909 } |
| 910 } | 910 } |
| 911 | 911 |
| 912 if (ok) { | 912 if (ok) { |
| 913 result = factory()->NewFunctionLiteral( | 913 result = factory()->NewFunctionLiteral( |
| 914 no_name, | 914 ast_value_factory_->empty_string(), |
| 915 ast_value_factory_, |
| 915 scope_, | 916 scope_, |
| 916 body, | 917 body, |
| 917 function_state.materialized_literal_count(), | 918 function_state.materialized_literal_count(), |
| 918 function_state.expected_property_count(), | 919 function_state.expected_property_count(), |
| 919 function_state.handler_count(), | 920 function_state.handler_count(), |
| 920 0, | 921 0, |
| 921 FunctionLiteral::kNoDuplicateParameters, | 922 FunctionLiteral::kNoDuplicateParameters, |
| 922 FunctionLiteral::ANONYMOUS_EXPRESSION, | 923 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 923 FunctionLiteral::kGlobalOrEval, | 924 FunctionLiteral::kGlobalOrEval, |
| 924 FunctionLiteral::kNotParenthesized, | 925 FunctionLiteral::kNotParenthesized, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 } | 977 } |
| 977 | 978 |
| 978 | 979 |
| 979 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 980 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 980 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 981 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 981 scanner_.Initialize(source); | 982 scanner_.Initialize(source); |
| 982 ASSERT(scope_ == NULL); | 983 ASSERT(scope_ == NULL); |
| 983 ASSERT(target_stack_ == NULL); | 984 ASSERT(target_stack_ == NULL); |
| 984 | 985 |
| 985 Handle<String> name(String::cast(shared_info->name())); | 986 Handle<String> name(String::cast(shared_info->name())); |
| 986 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 987 ASSERT(ast_value_factory_); |
| 987 fni_->PushEnclosingName(name); | 988 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 989 const AstString* raw_name = ast_value_factory_->GetString(name); |
| 990 fni_->PushEnclosingName(raw_name); |
| 988 | 991 |
| 989 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 992 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 990 | 993 |
| 991 // Place holder for the result. | 994 // Place holder for the result. |
| 992 FunctionLiteral* result = NULL; | 995 FunctionLiteral* result = NULL; |
| 993 | 996 |
| 994 { | 997 { |
| 995 // Parse the function literal. | 998 // Parse the function literal. |
| 996 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 999 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 997 info()->SetGlobalScope(scope); | 1000 info()->SetGlobalScope(scope); |
| 998 if (!info()->closure().is_null()) { | 1001 if (!info()->closure().is_null()) { |
| 999 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 1002 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 1000 zone()); | 1003 zone()); |
| 1001 } | 1004 } |
| 1002 original_scope_ = scope; | 1005 original_scope_ = scope; |
| 1003 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 1006 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 1007 ast_value_factory_); |
| 1004 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1008 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| 1005 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 1009 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
| 1006 scope->SetStrictMode(shared_info->strict_mode()); | 1010 scope->SetStrictMode(shared_info->strict_mode()); |
| 1007 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1011 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 1008 ? (shared_info->is_anonymous() | 1012 ? (shared_info->is_anonymous() |
| 1009 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1013 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 1010 : FunctionLiteral::NAMED_EXPRESSION) | 1014 : FunctionLiteral::NAMED_EXPRESSION) |
| 1011 : FunctionLiteral::DECLARATION; | 1015 : FunctionLiteral::DECLARATION; |
| 1012 bool ok = true; | 1016 bool ok = true; |
| 1013 result = ParseFunctionLiteral(name, | 1017 result = ParseFunctionLiteral(raw_name, |
| 1014 Scanner::Location::invalid(), | 1018 Scanner::Location::invalid(), |
| 1015 false, // Strict mode name already checked. | 1019 false, // Strict mode name already checked. |
| 1016 shared_info->is_generator(), | 1020 shared_info->is_generator(), |
| 1017 RelocInfo::kNoPosition, | 1021 RelocInfo::kNoPosition, |
| 1018 function_type, | 1022 function_type, |
| 1019 &ok); | 1023 &ok); |
| 1020 // Make sure the results agree. | 1024 // Make sure the results agree. |
| 1021 ASSERT(ok == (result != NULL)); | 1025 ASSERT(ok == (result != NULL)); |
| 1022 } | 1026 } |
| 1023 | 1027 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 continue; | 1076 continue; |
| 1073 } | 1077 } |
| 1074 | 1078 |
| 1075 if (directive_prologue) { | 1079 if (directive_prologue) { |
| 1076 // A shot at a directive. | 1080 // A shot at a directive. |
| 1077 ExpressionStatement* e_stat; | 1081 ExpressionStatement* e_stat; |
| 1078 Literal* literal; | 1082 Literal* literal; |
| 1079 // Still processing directive prologue? | 1083 // Still processing directive prologue? |
| 1080 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1084 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1081 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1085 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1082 literal->value()->IsString()) { | 1086 literal->raw_value()->IsString()) { |
| 1083 Handle<String> directive = Handle<String>::cast(literal->value()); | |
| 1084 | |
| 1085 // Check "use strict" directive (ES5 14.1). | 1087 // Check "use strict" directive (ES5 14.1). |
| 1086 if (strict_mode() == SLOPPY && | 1088 if (strict_mode() == SLOPPY && |
| 1087 String::Equals(isolate()->factory()->use_strict_string(), | 1089 literal->raw_value()->AsString() == |
| 1088 directive) && | 1090 ast_value_factory_->use_strict_string() && |
| 1089 token_loc.end_pos - token_loc.beg_pos == | 1091 token_loc.end_pos - token_loc.beg_pos == 12) { |
| 1090 isolate()->heap()->use_strict_string()->length() + 2) { | |
| 1091 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1092 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 1092 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1093 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 1093 // add this scope in DoParseProgram(), but that requires adaptations | 1094 // add this scope in DoParseProgram(), but that requires adaptations |
| 1094 // all over the code base, so we go with a quick-fix for now. | 1095 // all over the code base, so we go with a quick-fix for now. |
| 1095 // In the same manner, we have to patch the parsing mode. | 1096 // In the same manner, we have to patch the parsing mode. |
| 1096 if (is_eval && !scope_->is_eval_scope()) { | 1097 if (is_eval && !scope_->is_eval_scope()) { |
| 1097 ASSERT(scope_->is_global_scope()); | 1098 ASSERT(scope_->is_global_scope()); |
| 1098 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1099 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 1099 scope->set_start_position(scope_->start_position()); | 1100 scope->set_start_position(scope_->start_position()); |
| 1100 scope->set_end_position(scope_->end_position()); | 1101 scope->set_end_position(scope_->end_position()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1111 } | 1112 } |
| 1112 } | 1113 } |
| 1113 | 1114 |
| 1114 processor->Add(stat, zone()); | 1115 processor->Add(stat, zone()); |
| 1115 } | 1116 } |
| 1116 | 1117 |
| 1117 return 0; | 1118 return 0; |
| 1118 } | 1119 } |
| 1119 | 1120 |
| 1120 | 1121 |
| 1121 Statement* Parser::ParseModuleElement(ZoneStringList* labels, | 1122 Statement* Parser::ParseModuleElement(ZoneList<const AstString*>* labels, |
| 1122 bool* ok) { | 1123 bool* ok) { |
| 1123 // (Ecma 262 5th Edition, clause 14): | 1124 // (Ecma 262 5th Edition, clause 14): |
| 1124 // SourceElement: | 1125 // SourceElement: |
| 1125 // Statement | 1126 // Statement |
| 1126 // FunctionDeclaration | 1127 // FunctionDeclaration |
| 1127 // | 1128 // |
| 1128 // In harmony mode we allow additionally the following productions | 1129 // In harmony mode we allow additionally the following productions |
| 1129 // ModuleElement: | 1130 // ModuleElement: |
| 1130 // LetDeclaration | 1131 // LetDeclaration |
| 1131 // ConstDeclaration | 1132 // ConstDeclaration |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1145 case Token::EXPORT: | 1146 case Token::EXPORT: |
| 1146 return ParseExportDeclaration(ok); | 1147 return ParseExportDeclaration(ok); |
| 1147 default: { | 1148 default: { |
| 1148 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1149 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 1149 // Handle 'module' as a context-sensitive keyword. | 1150 // Handle 'module' as a context-sensitive keyword. |
| 1150 if (FLAG_harmony_modules && | 1151 if (FLAG_harmony_modules && |
| 1151 peek() == Token::IDENTIFIER && | 1152 peek() == Token::IDENTIFIER && |
| 1152 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1153 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 1153 stmt != NULL) { | 1154 stmt != NULL) { |
| 1154 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1155 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
| 1155 if (estmt != NULL && | 1156 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
| 1156 estmt->expression()->AsVariableProxy() != NULL && | 1157 estmt->expression()->AsVariableProxy()->raw_name() == |
| 1157 String::Equals(isolate()->factory()->module_string(), | 1158 ast_value_factory_->module_string() && |
| 1158 estmt->expression()->AsVariableProxy()->name()) && | |
| 1159 !scanner()->literal_contains_escapes()) { | 1159 !scanner()->literal_contains_escapes()) { |
| 1160 return ParseModuleDeclaration(NULL, ok); | 1160 return ParseModuleDeclaration(NULL, ok); |
| 1161 } | 1161 } |
| 1162 } | 1162 } |
| 1163 return stmt; | 1163 return stmt; |
| 1164 } | 1164 } |
| 1165 } | 1165 } |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 | 1168 |
| 1169 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 1169 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstString*>* names, |
| 1170 bool* ok) { |
| 1170 // ModuleDeclaration: | 1171 // ModuleDeclaration: |
| 1171 // 'module' Identifier Module | 1172 // 'module' Identifier Module |
| 1172 | 1173 |
| 1173 int pos = peek_position(); | 1174 int pos = peek_position(); |
| 1174 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1175 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1175 | 1176 |
| 1176 #ifdef DEBUG | 1177 #ifdef DEBUG |
| 1177 if (FLAG_print_interface_details) | 1178 if (FLAG_print_interface_details) |
| 1178 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1179 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
| 1179 #endif | 1180 #endif |
| 1180 | 1181 |
| 1181 Module* module = ParseModule(CHECK_OK); | 1182 Module* module = ParseModule(CHECK_OK); |
| 1182 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1183 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 1183 Declaration* declaration = | 1184 Declaration* declaration = |
| 1184 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 1185 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
| 1185 Declare(declaration, true, CHECK_OK); | 1186 Declare(declaration, true, CHECK_OK); |
| 1186 | 1187 |
| 1187 #ifdef DEBUG | 1188 #ifdef DEBUG |
| 1188 if (FLAG_print_interface_details) | 1189 if (FLAG_print_interface_details) |
| 1189 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1190 PrintF("# Module %.*s ", name->length(), name->raw_data()); |
| 1190 | |
| 1191 if (FLAG_print_interfaces) { | 1191 if (FLAG_print_interfaces) { |
| 1192 PrintF("module %s : ", name->ToAsciiArray()); | 1192 PrintF("module %.*s: ", name->length(), name->raw_data()); |
| 1193 module->interface()->Print(); | 1193 module->interface()->Print(); |
| 1194 } | 1194 } |
| 1195 #endif | 1195 #endif |
| 1196 | 1196 |
| 1197 if (names) names->Add(name, zone()); | 1197 if (names) names->Add(name, zone()); |
| 1198 if (module->body() == NULL) | 1198 if (module->body() == NULL) |
| 1199 return factory()->NewEmptyStatement(pos); | 1199 return factory()->NewEmptyStatement(pos); |
| 1200 else | 1200 else |
| 1201 return factory()->NewModuleStatement(proxy, module->body(), pos); | 1201 return factory()->NewModuleStatement(proxy, module->body(), pos); |
| 1202 } | 1202 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1283 | 1283 |
| 1284 | 1284 |
| 1285 Module* Parser::ParseModulePath(bool* ok) { | 1285 Module* Parser::ParseModulePath(bool* ok) { |
| 1286 // ModulePath: | 1286 // ModulePath: |
| 1287 // Identifier | 1287 // Identifier |
| 1288 // ModulePath '.' Identifier | 1288 // ModulePath '.' Identifier |
| 1289 | 1289 |
| 1290 int pos = peek_position(); | 1290 int pos = peek_position(); |
| 1291 Module* result = ParseModuleVariable(CHECK_OK); | 1291 Module* result = ParseModuleVariable(CHECK_OK); |
| 1292 while (Check(Token::PERIOD)) { | 1292 while (Check(Token::PERIOD)) { |
| 1293 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1293 const AstString* name = ParseIdentifierName(CHECK_OK); |
| 1294 #ifdef DEBUG | 1294 #ifdef DEBUG |
| 1295 if (FLAG_print_interface_details) | 1295 if (FLAG_print_interface_details) |
| 1296 PrintF("# Path .%s ", name->ToAsciiArray()); | 1296 PrintF("# Path .%.*s ", name->length(), name->raw_data()); |
| 1297 #endif | 1297 #endif |
| 1298 Module* member = factory()->NewModulePath(result, name, pos); | 1298 Module* member = factory()->NewModulePath(result, name, pos); |
| 1299 result->interface()->Add(name, member->interface(), zone(), ok); | 1299 result->interface()->Add(name, member->interface(), zone(), ok); |
| 1300 if (!*ok) { | 1300 if (!*ok) { |
| 1301 #ifdef DEBUG | 1301 #ifdef DEBUG |
| 1302 if (FLAG_print_interfaces) { | 1302 if (FLAG_print_interfaces) { |
| 1303 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1303 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); |
| 1304 PrintF("result: "); | 1304 PrintF("result: "); |
| 1305 result->interface()->Print(); | 1305 result->interface()->Print(); |
| 1306 PrintF("member: "); | 1306 PrintF("member: "); |
| 1307 member->interface()->Print(); | 1307 member->interface()->Print(); |
| 1308 } | 1308 } |
| 1309 #endif | 1309 #endif |
| 1310 ParserTraits::ReportMessage("invalid_module_path", name); | 1310 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1311 return NULL; | 1311 return NULL; |
| 1312 } | 1312 } |
| 1313 result = member; | 1313 result = member; |
| 1314 } | 1314 } |
| 1315 | 1315 |
| 1316 return result; | 1316 return result; |
| 1317 } | 1317 } |
| 1318 | 1318 |
| 1319 | 1319 |
| 1320 Module* Parser::ParseModuleVariable(bool* ok) { | 1320 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1321 // ModulePath: | 1321 // ModulePath: |
| 1322 // Identifier | 1322 // Identifier |
| 1323 | 1323 |
| 1324 int pos = peek_position(); | 1324 int pos = peek_position(); |
| 1325 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1325 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1326 #ifdef DEBUG | 1326 #ifdef DEBUG |
| 1327 if (FLAG_print_interface_details) | 1327 if (FLAG_print_interface_details) |
| 1328 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1328 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); |
| 1329 #endif | 1329 #endif |
| 1330 VariableProxy* proxy = scope_->NewUnresolved( | 1330 VariableProxy* proxy = scope_->NewUnresolved( |
| 1331 factory(), name, Interface::NewModule(zone()), | 1331 factory(), name, Interface::NewModule(zone()), |
| 1332 scanner()->location().beg_pos); | 1332 scanner()->location().beg_pos); |
| 1333 | 1333 |
| 1334 return factory()->NewModuleVariable(proxy, pos); | 1334 return factory()->NewModuleVariable(proxy, pos); |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 | 1337 |
| 1338 Module* Parser::ParseModuleUrl(bool* ok) { | 1338 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1339 // Module: | 1339 // Module: |
| 1340 // String | 1340 // String |
| 1341 | 1341 |
| 1342 int pos = peek_position(); | 1342 int pos = peek_position(); |
| 1343 Expect(Token::STRING, CHECK_OK); | 1343 Expect(Token::STRING, CHECK_OK); |
| 1344 Handle<String> symbol = GetSymbol(); | 1344 const AstString* symbol = GetSymbol(scanner()); |
| 1345 | 1345 |
| 1346 // TODO(ES6): Request JS resource from environment... | 1346 // TODO(ES6): Request JS resource from environment... |
| 1347 | 1347 |
| 1348 #ifdef DEBUG | 1348 #ifdef DEBUG |
| 1349 if (FLAG_print_interface_details) PrintF("# Url "); | 1349 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1350 #endif | 1350 #endif |
| 1351 | 1351 |
| 1352 // Create an empty literal as long as the feature isn't finished. | 1352 // Create an empty literal as long as the feature isn't finished. |
| 1353 USE(symbol); | 1353 USE(symbol); |
| 1354 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1354 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1378 | 1378 |
| 1379 | 1379 |
| 1380 Block* Parser::ParseImportDeclaration(bool* ok) { | 1380 Block* Parser::ParseImportDeclaration(bool* ok) { |
| 1381 // ImportDeclaration: | 1381 // ImportDeclaration: |
| 1382 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1382 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1383 // | 1383 // |
| 1384 // TODO(ES6): implement destructuring ImportSpecifiers | 1384 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1385 | 1385 |
| 1386 int pos = peek_position(); | 1386 int pos = peek_position(); |
| 1387 Expect(Token::IMPORT, CHECK_OK); | 1387 Expect(Token::IMPORT, CHECK_OK); |
| 1388 ZoneStringList names(1, zone()); | 1388 ZoneList<const AstString*> names(1, zone()); |
| 1389 | 1389 |
| 1390 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1390 const AstString* name = ParseIdentifierName(CHECK_OK); |
| 1391 names.Add(name, zone()); | 1391 names.Add(name, zone()); |
| 1392 while (peek() == Token::COMMA) { | 1392 while (peek() == Token::COMMA) { |
| 1393 Consume(Token::COMMA); | 1393 Consume(Token::COMMA); |
| 1394 name = ParseIdentifierName(CHECK_OK); | 1394 name = ParseIdentifierName(CHECK_OK); |
| 1395 names.Add(name, zone()); | 1395 names.Add(name, zone()); |
| 1396 } | 1396 } |
| 1397 | 1397 |
| 1398 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1398 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1399 Module* module = ParseModuleSpecifier(CHECK_OK); | 1399 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1400 ExpectSemicolon(CHECK_OK); | 1400 ExpectSemicolon(CHECK_OK); |
| 1401 | 1401 |
| 1402 // Generate a separate declaration for each identifier. | 1402 // Generate a separate declaration for each identifier. |
| 1403 // TODO(ES6): once we implement destructuring, make that one declaration. | 1403 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1404 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1404 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 1405 for (int i = 0; i < names.length(); ++i) { | 1405 for (int i = 0; i < names.length(); ++i) { |
| 1406 #ifdef DEBUG | 1406 #ifdef DEBUG |
| 1407 if (FLAG_print_interface_details) | 1407 if (FLAG_print_interface_details) |
| 1408 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1408 PrintF("# Import %.*s ", name->length(), name->raw_data()); |
| 1409 #endif | 1409 #endif |
| 1410 Interface* interface = Interface::NewUnknown(zone()); | 1410 Interface* interface = Interface::NewUnknown(zone()); |
| 1411 module->interface()->Add(names[i], interface, zone(), ok); | 1411 module->interface()->Add(names[i], interface, zone(), ok); |
| 1412 if (!*ok) { | 1412 if (!*ok) { |
| 1413 #ifdef DEBUG | 1413 #ifdef DEBUG |
| 1414 if (FLAG_print_interfaces) { | 1414 if (FLAG_print_interfaces) { |
| 1415 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1415 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), |
| 1416 name->raw_data()); |
| 1416 PrintF("module: "); | 1417 PrintF("module: "); |
| 1417 module->interface()->Print(); | 1418 module->interface()->Print(); |
| 1418 } | 1419 } |
| 1419 #endif | 1420 #endif |
| 1420 ParserTraits::ReportMessage("invalid_module_path", name); | 1421 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1421 return NULL; | 1422 return NULL; |
| 1422 } | 1423 } |
| 1423 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1424 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1424 Declaration* declaration = | 1425 Declaration* declaration = |
| 1425 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1426 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1436 // 'export' VariableDeclaration | 1437 // 'export' VariableDeclaration |
| 1437 // 'export' FunctionDeclaration | 1438 // 'export' FunctionDeclaration |
| 1438 // 'export' GeneratorDeclaration | 1439 // 'export' GeneratorDeclaration |
| 1439 // 'export' ModuleDeclaration | 1440 // 'export' ModuleDeclaration |
| 1440 // | 1441 // |
| 1441 // TODO(ES6): implement structuring ExportSpecifiers | 1442 // TODO(ES6): implement structuring ExportSpecifiers |
| 1442 | 1443 |
| 1443 Expect(Token::EXPORT, CHECK_OK); | 1444 Expect(Token::EXPORT, CHECK_OK); |
| 1444 | 1445 |
| 1445 Statement* result = NULL; | 1446 Statement* result = NULL; |
| 1446 ZoneStringList names(1, zone()); | 1447 ZoneList<const AstString*> names(1, zone()); |
| 1447 switch (peek()) { | 1448 switch (peek()) { |
| 1448 case Token::IDENTIFIER: { | 1449 case Token::IDENTIFIER: { |
| 1449 int pos = position(); | 1450 int pos = position(); |
| 1450 Handle<String> name = | 1451 const AstString* name = |
| 1451 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1452 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1452 // Handle 'module' as a context-sensitive keyword. | 1453 // Handle 'module' as a context-sensitive keyword. |
| 1453 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1454 if (name != ast_value_factory_->module_string()) { |
| 1454 names.Add(name, zone()); | 1455 names.Add(name, zone()); |
| 1455 while (peek() == Token::COMMA) { | 1456 while (peek() == Token::COMMA) { |
| 1456 Consume(Token::COMMA); | 1457 Consume(Token::COMMA); |
| 1457 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1458 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1458 names.Add(name, zone()); | 1459 names.Add(name, zone()); |
| 1459 } | 1460 } |
| 1460 ExpectSemicolon(CHECK_OK); | 1461 ExpectSemicolon(CHECK_OK); |
| 1461 result = factory()->NewEmptyStatement(pos); | 1462 result = factory()->NewEmptyStatement(pos); |
| 1462 } else { | 1463 } else { |
| 1463 result = ParseModuleDeclaration(&names, CHECK_OK); | 1464 result = ParseModuleDeclaration(&names, CHECK_OK); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1479 *ok = false; | 1480 *ok = false; |
| 1480 ReportUnexpectedToken(scanner()->current_token()); | 1481 ReportUnexpectedToken(scanner()->current_token()); |
| 1481 return NULL; | 1482 return NULL; |
| 1482 } | 1483 } |
| 1483 | 1484 |
| 1484 // Extract declared names into export declarations and interface. | 1485 // Extract declared names into export declarations and interface. |
| 1485 Interface* interface = scope_->interface(); | 1486 Interface* interface = scope_->interface(); |
| 1486 for (int i = 0; i < names.length(); ++i) { | 1487 for (int i = 0; i < names.length(); ++i) { |
| 1487 #ifdef DEBUG | 1488 #ifdef DEBUG |
| 1488 if (FLAG_print_interface_details) | 1489 if (FLAG_print_interface_details) |
| 1489 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1490 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
| 1490 #endif | 1491 #endif |
| 1491 Interface* inner = Interface::NewUnknown(zone()); | 1492 Interface* inner = Interface::NewUnknown(zone()); |
| 1492 interface->Add(names[i], inner, zone(), CHECK_OK); | 1493 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1493 if (!*ok) | 1494 if (!*ok) |
| 1494 return NULL; | 1495 return NULL; |
| 1495 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1496 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1496 USE(proxy); | 1497 USE(proxy); |
| 1497 // TODO(rossberg): Rethink whether we actually need to store export | 1498 // TODO(rossberg): Rethink whether we actually need to store export |
| 1498 // declarations (for compilation?). | 1499 // declarations (for compilation?). |
| 1499 // ExportDeclaration* declaration = | 1500 // ExportDeclaration* declaration = |
| 1500 // factory()->NewExportDeclaration(proxy, scope_, position); | 1501 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1501 // scope_->AddDeclaration(declaration); | 1502 // scope_->AddDeclaration(declaration); |
| 1502 } | 1503 } |
| 1503 | 1504 |
| 1504 ASSERT(result != NULL); | 1505 ASSERT(result != NULL); |
| 1505 return result; | 1506 return result; |
| 1506 } | 1507 } |
| 1507 | 1508 |
| 1508 | 1509 |
| 1509 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1510 Statement* Parser::ParseBlockElement(ZoneList<const AstString*>* labels, |
| 1510 bool* ok) { | 1511 bool* ok) { |
| 1511 // (Ecma 262 5th Edition, clause 14): | 1512 // (Ecma 262 5th Edition, clause 14): |
| 1512 // SourceElement: | 1513 // SourceElement: |
| 1513 // Statement | 1514 // Statement |
| 1514 // FunctionDeclaration | 1515 // FunctionDeclaration |
| 1515 // | 1516 // |
| 1516 // In harmony mode we allow additionally the following productions | 1517 // In harmony mode we allow additionally the following productions |
| 1517 // BlockElement (aka SourceElement): | 1518 // BlockElement (aka SourceElement): |
| 1518 // LetDeclaration | 1519 // LetDeclaration |
| 1519 // ConstDeclaration | 1520 // ConstDeclaration |
| 1520 // GeneratorDeclaration | 1521 // GeneratorDeclaration |
| 1521 | 1522 |
| 1522 switch (peek()) { | 1523 switch (peek()) { |
| 1523 case Token::FUNCTION: | 1524 case Token::FUNCTION: |
| 1524 return ParseFunctionDeclaration(NULL, ok); | 1525 return ParseFunctionDeclaration(NULL, ok); |
| 1525 case Token::LET: | 1526 case Token::LET: |
| 1526 case Token::CONST: | 1527 case Token::CONST: |
| 1527 return ParseVariableStatement(kModuleElement, NULL, ok); | 1528 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1528 default: | 1529 default: |
| 1529 return ParseStatement(labels, ok); | 1530 return ParseStatement(labels, ok); |
| 1530 } | 1531 } |
| 1531 } | 1532 } |
| 1532 | 1533 |
| 1533 | 1534 |
| 1534 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1535 Statement* Parser::ParseStatement(ZoneList<const AstString*>* labels, |
| 1536 bool* ok) { |
| 1535 // Statement :: | 1537 // Statement :: |
| 1536 // Block | 1538 // Block |
| 1537 // VariableStatement | 1539 // VariableStatement |
| 1538 // EmptyStatement | 1540 // EmptyStatement |
| 1539 // ExpressionStatement | 1541 // ExpressionStatement |
| 1540 // IfStatement | 1542 // IfStatement |
| 1541 // IterationStatement | 1543 // IterationStatement |
| 1542 // ContinueStatement | 1544 // ContinueStatement |
| 1543 // BreakStatement | 1545 // BreakStatement |
| 1544 // ReturnStatement | 1546 // ReturnStatement |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 | 1636 |
| 1635 case Token::DEBUGGER: | 1637 case Token::DEBUGGER: |
| 1636 return ParseDebuggerStatement(ok); | 1638 return ParseDebuggerStatement(ok); |
| 1637 | 1639 |
| 1638 default: | 1640 default: |
| 1639 return ParseExpressionOrLabelledStatement(labels, ok); | 1641 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1640 } | 1642 } |
| 1641 } | 1643 } |
| 1642 | 1644 |
| 1643 | 1645 |
| 1644 VariableProxy* Parser::NewUnresolved( | 1646 VariableProxy* Parser::NewUnresolved(const AstString* name, VariableMode mode, |
| 1645 Handle<String> name, VariableMode mode, Interface* interface) { | 1647 Interface* interface) { |
| 1646 // If we are inside a function, a declaration of a var/const variable is a | 1648 // If we are inside a function, a declaration of a var/const variable is a |
| 1647 // truly local variable, and the scope of the variable is always the function | 1649 // truly local variable, and the scope of the variable is always the function |
| 1648 // scope. | 1650 // scope. |
| 1649 // Let/const variables in harmony mode are always added to the immediately | 1651 // Let/const variables in harmony mode are always added to the immediately |
| 1650 // enclosing scope. | 1652 // enclosing scope. |
| 1651 return DeclarationScope(mode)->NewUnresolved( | 1653 return DeclarationScope(mode)->NewUnresolved( |
| 1652 factory(), name, interface, position()); | 1654 factory(), name, interface, position()); |
| 1653 } | 1655 } |
| 1654 | 1656 |
| 1655 | 1657 |
| 1656 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1658 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1657 VariableProxy* proxy = declaration->proxy(); | 1659 VariableProxy* proxy = declaration->proxy(); |
| 1658 Handle<String> name = proxy->name(); | 1660 ASSERT(proxy->raw_name() != NULL); |
| 1661 const AstString* name = proxy->raw_name(); |
| 1659 VariableMode mode = declaration->mode(); | 1662 VariableMode mode = declaration->mode(); |
| 1660 Scope* declaration_scope = DeclarationScope(mode); | 1663 Scope* declaration_scope = DeclarationScope(mode); |
| 1661 Variable* var = NULL; | 1664 Variable* var = NULL; |
| 1662 | 1665 |
| 1663 // If a suitable scope exists, then we can statically declare this | 1666 // If a suitable scope exists, then we can statically declare this |
| 1664 // variable and also set its mode. In any case, a Declaration node | 1667 // variable and also set its mode. In any case, a Declaration node |
| 1665 // will be added to the scope so that the declaration can be added | 1668 // will be added to the scope so that the declaration can be added |
| 1666 // to the corresponding activation frame at runtime if necessary. | 1669 // to the corresponding activation frame at runtime if necessary. |
| 1667 // For instance declarations inside an eval scope need to be added | 1670 // For instance declarations inside an eval scope need to be added |
| 1668 // to the calling function context. | 1671 // to the calling function context. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 // with a context slot index and a context chain length for this | 1779 // with a context slot index and a context chain length for this |
| 1777 // initialization code. Thus, inside the 'with' statement, we need | 1780 // initialization code. Thus, inside the 'with' statement, we need |
| 1778 // both access to the static and the dynamic context chain; the | 1781 // both access to the static and the dynamic context chain; the |
| 1779 // runtime needs to provide both. | 1782 // runtime needs to provide both. |
| 1780 if (resolve && var != NULL) { | 1783 if (resolve && var != NULL) { |
| 1781 proxy->BindTo(var); | 1784 proxy->BindTo(var); |
| 1782 | 1785 |
| 1783 if (FLAG_harmony_modules) { | 1786 if (FLAG_harmony_modules) { |
| 1784 bool ok; | 1787 bool ok; |
| 1785 #ifdef DEBUG | 1788 #ifdef DEBUG |
| 1786 if (FLAG_print_interface_details) | 1789 if (FLAG_print_interface_details) { |
| 1787 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); | 1790 PrintF("# Declare %.*s ", var->raw_name()->length(), |
| 1791 var->raw_name()->raw_data()); |
| 1792 } |
| 1788 #endif | 1793 #endif |
| 1789 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1794 proxy->interface()->Unify(var->interface(), zone(), &ok); |
| 1790 if (!ok) { | 1795 if (!ok) { |
| 1791 #ifdef DEBUG | 1796 #ifdef DEBUG |
| 1792 if (FLAG_print_interfaces) { | 1797 if (FLAG_print_interfaces) { |
| 1793 PrintF("DECLARE TYPE ERROR\n"); | 1798 PrintF("DECLARE TYPE ERROR\n"); |
| 1794 PrintF("proxy: "); | 1799 PrintF("proxy: "); |
| 1795 proxy->interface()->Print(); | 1800 proxy->interface()->Print(); |
| 1796 PrintF("var: "); | 1801 PrintF("var: "); |
| 1797 var->interface()->Print(); | 1802 var->interface()->Print(); |
| 1798 } | 1803 } |
| 1799 #endif | 1804 #endif |
| 1800 ParserTraits::ReportMessage("module_type_error", name); | 1805 ParserTraits::ReportMessage("module_type_error", name); |
| 1801 } | 1806 } |
| 1802 } | 1807 } |
| 1803 } | 1808 } |
| 1804 } | 1809 } |
| 1805 | 1810 |
| 1806 | 1811 |
| 1807 // Language extension which is only enabled for source files loaded | 1812 // Language extension which is only enabled for source files loaded |
| 1808 // through the API's extension mechanism. A native function | 1813 // through the API's extension mechanism. A native function |
| 1809 // declaration is resolved by looking up the function through a | 1814 // declaration is resolved by looking up the function through a |
| 1810 // callback provided by the extension. | 1815 // callback provided by the extension. |
| 1811 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1816 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1812 int pos = peek_position(); | 1817 int pos = peek_position(); |
| 1813 Expect(Token::FUNCTION, CHECK_OK); | 1818 Expect(Token::FUNCTION, CHECK_OK); |
| 1814 // Allow "eval" or "arguments" for backward compatibility. | 1819 // Allow "eval" or "arguments" for backward compatibility. |
| 1815 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1820 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1816 Expect(Token::LPAREN, CHECK_OK); | 1821 Expect(Token::LPAREN, CHECK_OK); |
| 1817 bool done = (peek() == Token::RPAREN); | 1822 bool done = (peek() == Token::RPAREN); |
| 1818 while (!done) { | 1823 while (!done) { |
| 1819 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1824 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1820 done = (peek() == Token::RPAREN); | 1825 done = (peek() == Token::RPAREN); |
| 1821 if (!done) { | 1826 if (!done) { |
| 1822 Expect(Token::COMMA, CHECK_OK); | 1827 Expect(Token::COMMA, CHECK_OK); |
| 1823 } | 1828 } |
| 1824 } | 1829 } |
| 1825 Expect(Token::RPAREN, CHECK_OK); | 1830 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1840 Declare(declaration, true, CHECK_OK); | 1845 Declare(declaration, true, CHECK_OK); |
| 1841 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1846 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1842 name, extension_, RelocInfo::kNoPosition); | 1847 name, extension_, RelocInfo::kNoPosition); |
| 1843 return factory()->NewExpressionStatement( | 1848 return factory()->NewExpressionStatement( |
| 1844 factory()->NewAssignment( | 1849 factory()->NewAssignment( |
| 1845 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1850 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1846 pos); | 1851 pos); |
| 1847 } | 1852 } |
| 1848 | 1853 |
| 1849 | 1854 |
| 1850 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1855 Statement* Parser::ParseFunctionDeclaration(ZoneList<const AstString*>* names, |
| 1856 bool* ok) { |
| 1851 // FunctionDeclaration :: | 1857 // FunctionDeclaration :: |
| 1852 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1858 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1853 // GeneratorDeclaration :: | 1859 // GeneratorDeclaration :: |
| 1854 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1860 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1855 // '{' FunctionBody '}' | 1861 // '{' FunctionBody '}' |
| 1856 Expect(Token::FUNCTION, CHECK_OK); | 1862 Expect(Token::FUNCTION, CHECK_OK); |
| 1857 int pos = position(); | 1863 int pos = position(); |
| 1858 bool is_generator = allow_generators() && Check(Token::MUL); | 1864 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1859 bool is_strict_reserved = false; | 1865 bool is_strict_reserved = false; |
| 1860 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1866 const AstString* name = ParseIdentifierOrStrictReservedWord( |
| 1861 &is_strict_reserved, CHECK_OK); | 1867 &is_strict_reserved, CHECK_OK); |
| 1862 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1868 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1863 scanner()->location(), | 1869 scanner()->location(), |
| 1864 is_strict_reserved, | 1870 is_strict_reserved, |
| 1865 is_generator, | 1871 is_generator, |
| 1866 pos, | 1872 pos, |
| 1867 FunctionLiteral::DECLARATION, | 1873 FunctionLiteral::DECLARATION, |
| 1868 CHECK_OK); | 1874 CHECK_OK); |
| 1869 // Even if we're not at the top-level of the global or a function | 1875 // Even if we're not at the top-level of the global or a function |
| 1870 // scope, we treat it as such and introduce the function with its | 1876 // scope, we treat it as such and introduce the function with its |
| 1871 // initial value upon entering the corresponding scope. | 1877 // initial value upon entering the corresponding scope. |
| 1872 // In extended mode, a function behaves as a lexical binding, except in the | 1878 // In extended mode, a function behaves as a lexical binding, except in the |
| 1873 // global scope. | 1879 // global scope. |
| 1874 VariableMode mode = | 1880 VariableMode mode = |
| 1875 allow_harmony_scoping() && | 1881 allow_harmony_scoping() && |
| 1876 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1882 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| 1877 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1883 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1878 Declaration* declaration = | 1884 Declaration* declaration = |
| 1879 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1885 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1880 Declare(declaration, true, CHECK_OK); | 1886 Declare(declaration, true, CHECK_OK); |
| 1881 if (names) names->Add(name, zone()); | 1887 if (names) names->Add(name, zone()); |
| 1882 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1888 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1883 } | 1889 } |
| 1884 | 1890 |
| 1885 | 1891 |
| 1886 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1892 Block* Parser::ParseBlock(ZoneList<const AstString*>* labels, bool* ok) { |
| 1887 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1893 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1888 return ParseScopedBlock(labels, ok); | 1894 return ParseScopedBlock(labels, ok); |
| 1889 } | 1895 } |
| 1890 | 1896 |
| 1891 // Block :: | 1897 // Block :: |
| 1892 // '{' Statement* '}' | 1898 // '{' Statement* '}' |
| 1893 | 1899 |
| 1894 // Note that a Block does not introduce a new execution scope! | 1900 // Note that a Block does not introduce a new execution scope! |
| 1895 // (ECMA-262, 3rd, 12.2) | 1901 // (ECMA-262, 3rd, 12.2) |
| 1896 // | 1902 // |
| 1897 // Construct block expecting 16 statements. | 1903 // Construct block expecting 16 statements. |
| 1898 Block* result = | 1904 Block* result = |
| 1899 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1905 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1900 Target target(&this->target_stack_, result); | 1906 Target target(&this->target_stack_, result); |
| 1901 Expect(Token::LBRACE, CHECK_OK); | 1907 Expect(Token::LBRACE, CHECK_OK); |
| 1902 while (peek() != Token::RBRACE) { | 1908 while (peek() != Token::RBRACE) { |
| 1903 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1909 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1904 if (stat && !stat->IsEmpty()) { | 1910 if (stat && !stat->IsEmpty()) { |
| 1905 result->AddStatement(stat, zone()); | 1911 result->AddStatement(stat, zone()); |
| 1906 } | 1912 } |
| 1907 } | 1913 } |
| 1908 Expect(Token::RBRACE, CHECK_OK); | 1914 Expect(Token::RBRACE, CHECK_OK); |
| 1909 return result; | 1915 return result; |
| 1910 } | 1916 } |
| 1911 | 1917 |
| 1912 | 1918 |
| 1913 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1919 Block* Parser::ParseScopedBlock(ZoneList<const AstString*>* labels, bool* ok) { |
| 1914 // The harmony mode uses block elements instead of statements. | 1920 // The harmony mode uses block elements instead of statements. |
| 1915 // | 1921 // |
| 1916 // Block :: | 1922 // Block :: |
| 1917 // '{' BlockElement* '}' | 1923 // '{' BlockElement* '}' |
| 1918 | 1924 |
| 1919 // Construct block expecting 16 statements. | 1925 // Construct block expecting 16 statements. |
| 1920 Block* body = | 1926 Block* body = |
| 1921 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1927 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1922 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1928 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 1923 | 1929 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1938 } | 1944 } |
| 1939 Expect(Token::RBRACE, CHECK_OK); | 1945 Expect(Token::RBRACE, CHECK_OK); |
| 1940 block_scope->set_end_position(scanner()->location().end_pos); | 1946 block_scope->set_end_position(scanner()->location().end_pos); |
| 1941 block_scope = block_scope->FinalizeBlockScope(); | 1947 block_scope = block_scope->FinalizeBlockScope(); |
| 1942 body->set_scope(block_scope); | 1948 body->set_scope(block_scope); |
| 1943 return body; | 1949 return body; |
| 1944 } | 1950 } |
| 1945 | 1951 |
| 1946 | 1952 |
| 1947 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1953 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1948 ZoneStringList* names, | 1954 ZoneList<const AstString*>* names, |
| 1949 bool* ok) { | 1955 bool* ok) { |
| 1950 // VariableStatement :: | 1956 // VariableStatement :: |
| 1951 // VariableDeclarations ';' | 1957 // VariableDeclarations ';' |
| 1952 | 1958 |
| 1953 Handle<String> ignore; | 1959 const AstString* ignore; |
| 1954 Block* result = | 1960 Block* result = |
| 1955 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1961 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1956 ExpectSemicolon(CHECK_OK); | 1962 ExpectSemicolon(CHECK_OK); |
| 1957 return result; | 1963 return result; |
| 1958 } | 1964 } |
| 1959 | 1965 |
| 1960 | 1966 |
| 1961 // If the variable declaration declares exactly one non-const | 1967 // If the variable declaration declares exactly one non-const |
| 1962 // variable, then *out is set to that variable. In all other cases, | 1968 // variable, then *out is set to that variable. In all other cases, |
| 1963 // *out is untouched; in particular, it is the caller's responsibility | 1969 // *out is untouched; in particular, it is the caller's responsibility |
| 1964 // to initialize it properly. This mechanism is used for the parsing | 1970 // to initialize it properly. This mechanism is used for the parsing |
| 1965 // of 'for-in' loops. | 1971 // of 'for-in' loops. |
| 1966 Block* Parser::ParseVariableDeclarations( | 1972 Block* Parser::ParseVariableDeclarations( |
| 1967 VariableDeclarationContext var_context, | 1973 VariableDeclarationContext var_context, |
| 1968 VariableDeclarationProperties* decl_props, | 1974 VariableDeclarationProperties* decl_props, |
| 1969 ZoneStringList* names, | 1975 ZoneList<const AstString*>* names, |
| 1970 Handle<String>* out, | 1976 const AstString** out, |
| 1971 bool* ok) { | 1977 bool* ok) { |
| 1972 // VariableDeclarations :: | 1978 // VariableDeclarations :: |
| 1973 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 1979 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1974 // | 1980 // |
| 1975 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1981 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1976 // | 1982 // |
| 1977 // ConstDeclaration :: | 1983 // ConstDeclaration :: |
| 1978 // const ConstBinding (',' ConstBinding)* ';' | 1984 // const ConstBinding (',' ConstBinding)* ';' |
| 1979 // ConstBinding :: | 1985 // ConstBinding :: |
| 1980 // Identifier '=' AssignmentExpression | 1986 // Identifier '=' AssignmentExpression |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2068 // | 2074 // |
| 2069 // We mark the block as initializer block because we don't want the | 2075 // We mark the block as initializer block because we don't want the |
| 2070 // rewriter to add a '.result' assignment to such a block (to get compliant | 2076 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 2071 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2077 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 2072 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2078 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 2073 // is inside an initializer block, it is ignored. | 2079 // is inside an initializer block, it is ignored. |
| 2074 // | 2080 // |
| 2075 // Create new block with one expected declaration. | 2081 // Create new block with one expected declaration. |
| 2076 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2082 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 2077 int nvars = 0; // the number of variables declared | 2083 int nvars = 0; // the number of variables declared |
| 2078 Handle<String> name; | 2084 const AstString* name = NULL; |
| 2079 do { | 2085 do { |
| 2080 if (fni_ != NULL) fni_->Enter(); | 2086 if (fni_ != NULL) fni_->Enter(); |
| 2081 | 2087 |
| 2082 // Parse variable name. | 2088 // Parse variable name. |
| 2083 if (nvars > 0) Consume(Token::COMMA); | 2089 if (nvars > 0) Consume(Token::COMMA); |
| 2084 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2090 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2085 if (fni_ != NULL) fni_->PushVariableName(name); | 2091 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2086 | 2092 |
| 2087 // Declare variable. | 2093 // Declare variable. |
| 2088 // Note that we *always* must treat the initial value via a separate init | 2094 // Note that we *always* must treat the initial value via a separate init |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 // properties in the prototype chain, but only after the variable | 2193 // properties in the prototype chain, but only after the variable |
| 2188 // declaration statement has been executed. This is important in | 2194 // declaration statement has been executed. This is important in |
| 2189 // browsers where the global object (window) has lots of | 2195 // browsers where the global object (window) has lots of |
| 2190 // properties defined in prototype objects. | 2196 // properties defined in prototype objects. |
| 2191 if (initialization_scope->is_global_scope() && | 2197 if (initialization_scope->is_global_scope() && |
| 2192 !IsLexicalVariableMode(mode)) { | 2198 !IsLexicalVariableMode(mode)) { |
| 2193 // Compute the arguments for the runtime call. | 2199 // Compute the arguments for the runtime call. |
| 2194 ZoneList<Expression*>* arguments = | 2200 ZoneList<Expression*>* arguments = |
| 2195 new(zone()) ZoneList<Expression*>(3, zone()); | 2201 new(zone()) ZoneList<Expression*>(3, zone()); |
| 2196 // We have at least 1 parameter. | 2202 // We have at least 1 parameter. |
| 2197 arguments->Add(factory()->NewLiteral(name, pos), zone()); | 2203 arguments->Add(factory()->NewStringLiteral(name, pos), zone()); |
| 2198 CallRuntime* initialize; | 2204 CallRuntime* initialize; |
| 2199 | 2205 |
| 2200 if (is_const) { | 2206 if (is_const) { |
| 2201 arguments->Add(value, zone()); | 2207 arguments->Add(value, zone()); |
| 2202 value = NULL; // zap the value to avoid the unnecessary assignment | 2208 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2203 | 2209 |
| 2204 // Construct the call to Runtime_InitializeConstGlobal | 2210 // Construct the call to Runtime_InitializeConstGlobal |
| 2205 // and add it to the initialization statement block. | 2211 // and add it to the initialization statement block. |
| 2206 // Note that the function does different things depending on | 2212 // Note that the function does different things depending on |
| 2207 // the number of arguments (1 or 2). | 2213 // the number of arguments (1 or 2). |
| 2208 initialize = factory()->NewCallRuntime( | 2214 initialize = factory()->NewCallRuntime( |
| 2209 isolate()->factory()->InitializeConstGlobal_string(), | 2215 ast_value_factory_->initialize_const_global_string(), |
| 2210 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), | 2216 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
| 2211 arguments, pos); | 2217 arguments, pos); |
| 2212 } else { | 2218 } else { |
| 2213 // Add strict mode. | 2219 // Add strict mode. |
| 2214 // We may want to pass singleton to avoid Literal allocations. | 2220 // We may want to pass singleton to avoid Literal allocations. |
| 2215 StrictMode strict_mode = initialization_scope->strict_mode(); | 2221 StrictMode strict_mode = initialization_scope->strict_mode(); |
| 2216 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2222 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
| 2217 | 2223 |
| 2218 // Be careful not to assign a value to the global variable if | 2224 // Be careful not to assign a value to the global variable if |
| 2219 // we're in a with. The initialization value should not | 2225 // we're in a with. The initialization value should not |
| 2220 // necessarily be stored in the global object in that case, | 2226 // necessarily be stored in the global object in that case, |
| 2221 // which is why we need to generate a separate assignment node. | 2227 // which is why we need to generate a separate assignment node. |
| 2222 if (value != NULL && !inside_with()) { | 2228 if (value != NULL && !inside_with()) { |
| 2223 arguments->Add(value, zone()); | 2229 arguments->Add(value, zone()); |
| 2224 value = NULL; // zap the value to avoid the unnecessary assignment | 2230 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2225 } | 2231 } |
| 2226 | 2232 |
| 2227 // Construct the call to Runtime_InitializeVarGlobal | 2233 // Construct the call to Runtime_InitializeVarGlobal |
| 2228 // and add it to the initialization statement block. | 2234 // and add it to the initialization statement block. |
| 2229 // Note that the function does different things depending on | 2235 // Note that the function does different things depending on |
| 2230 // the number of arguments (2 or 3). | 2236 // the number of arguments (2 or 3). |
| 2231 initialize = factory()->NewCallRuntime( | 2237 initialize = factory()->NewCallRuntime( |
| 2232 isolate()->factory()->InitializeVarGlobal_string(), | 2238 ast_value_factory_->initialize_var_global_string(), |
| 2233 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2239 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 2234 arguments, pos); | 2240 arguments, pos); |
| 2235 } | 2241 } |
| 2236 | 2242 |
| 2237 block->AddStatement( | 2243 block->AddStatement( |
| 2238 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 2244 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
| 2239 zone()); | 2245 zone()); |
| 2240 } else if (needs_init) { | 2246 } else if (needs_init) { |
| 2241 // Constant initializations always assign to the declared constant which | 2247 // Constant initializations always assign to the declared constant which |
| 2242 // is always at the function scope level. This is only relevant for | 2248 // 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... |
| 2278 // If there was a single non-const declaration, return it in the output | 2284 // If there was a single non-const declaration, return it in the output |
| 2279 // parameter for possible use by for/in. | 2285 // parameter for possible use by for/in. |
| 2280 if (nvars == 1 && !is_const) { | 2286 if (nvars == 1 && !is_const) { |
| 2281 *out = name; | 2287 *out = name; |
| 2282 } | 2288 } |
| 2283 | 2289 |
| 2284 return block; | 2290 return block; |
| 2285 } | 2291 } |
| 2286 | 2292 |
| 2287 | 2293 |
| 2288 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { | 2294 static bool ContainsLabel(ZoneList<const AstString*>* labels, |
| 2289 ASSERT(!label.is_null()); | 2295 const AstString* label) { |
| 2296 ASSERT(label != NULL); |
| 2290 if (labels != NULL) { | 2297 if (labels != NULL) { |
| 2291 for (int i = labels->length(); i-- > 0; ) { | 2298 for (int i = labels->length(); i-- > 0; ) { |
| 2292 if (labels->at(i).is_identical_to(label)) { | 2299 if (labels->at(i) == label) { |
| 2293 return true; | 2300 return true; |
| 2294 } | 2301 } |
| 2295 } | 2302 } |
| 2296 } | 2303 } |
| 2297 return false; | 2304 return false; |
| 2298 } | 2305 } |
| 2299 | 2306 |
| 2300 | 2307 |
| 2301 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2308 Statement* Parser::ParseExpressionOrLabelledStatement( |
| 2302 bool* ok) { | 2309 ZoneList<const AstString*>* labels, bool* ok) { |
| 2303 // ExpressionStatement | LabelledStatement :: | 2310 // ExpressionStatement | LabelledStatement :: |
| 2304 // Expression ';' | 2311 // Expression ';' |
| 2305 // Identifier ':' Statement | 2312 // Identifier ':' Statement |
| 2306 int pos = peek_position(); | 2313 int pos = peek_position(); |
| 2307 bool starts_with_idenfifier = peek_any_identifier(); | 2314 bool starts_with_idenfifier = peek_any_identifier(); |
| 2308 Expression* expr = ParseExpression(true, CHECK_OK); | 2315 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2309 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2316 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
| 2310 expr->AsVariableProxy() != NULL && | 2317 expr->AsVariableProxy() != NULL && |
| 2311 !expr->AsVariableProxy()->is_this()) { | 2318 !expr->AsVariableProxy()->is_this()) { |
| 2312 // Expression is a single identifier, and not, e.g., a parenthesized | 2319 // Expression is a single identifier, and not, e.g., a parenthesized |
| 2313 // identifier. | 2320 // identifier. |
| 2314 VariableProxy* var = expr->AsVariableProxy(); | 2321 VariableProxy* var = expr->AsVariableProxy(); |
| 2315 Handle<String> label = var->name(); | 2322 const AstString* label = var->raw_name(); |
| 2316 // TODO(1240780): We don't check for redeclaration of labels | 2323 // TODO(1240780): We don't check for redeclaration of labels |
| 2317 // during preparsing since keeping track of the set of active | 2324 // during preparsing since keeping track of the set of active |
| 2318 // labels requires nontrivial changes to the way scopes are | 2325 // labels requires nontrivial changes to the way scopes are |
| 2319 // structured. However, these are probably changes we want to | 2326 // structured. However, these are probably changes we want to |
| 2320 // make later anyway so we should go back and fix this then. | 2327 // make later anyway so we should go back and fix this then. |
| 2321 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2328 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
| 2322 ParserTraits::ReportMessage("label_redeclaration", label); | 2329 ParserTraits::ReportMessage("label_redeclaration", label); |
| 2323 *ok = false; | 2330 *ok = false; |
| 2324 return NULL; | 2331 return NULL; |
| 2325 } | 2332 } |
| 2326 if (labels == NULL) { | 2333 if (labels == NULL) { |
| 2327 labels = new(zone()) ZoneStringList(4, zone()); | 2334 labels = new(zone()) ZoneList<const AstString*>(4, zone()); |
| 2328 } | 2335 } |
| 2329 labels->Add(label, zone()); | 2336 labels->Add(label, zone()); |
| 2330 // Remove the "ghost" variable that turned out to be a label | 2337 // Remove the "ghost" variable that turned out to be a label |
| 2331 // from the top scope. This way, we don't try to resolve it | 2338 // from the top scope. This way, we don't try to resolve it |
| 2332 // during the scope processing. | 2339 // during the scope processing. |
| 2333 scope_->RemoveUnresolved(var); | 2340 scope_->RemoveUnresolved(var); |
| 2334 Expect(Token::COLON, CHECK_OK); | 2341 Expect(Token::COLON, CHECK_OK); |
| 2335 return ParseStatement(labels, ok); | 2342 return ParseStatement(labels, ok); |
| 2336 } | 2343 } |
| 2337 | 2344 |
| 2338 // If we have an extension, we allow a native function declaration. | 2345 // If we have an extension, we allow a native function declaration. |
| 2339 // A native function declaration starts with "native function" with | 2346 // A native function declaration starts with "native function" with |
| 2340 // no line-terminator between the two words. | 2347 // no line-terminator between the two words. |
| 2341 if (extension_ != NULL && | 2348 if (extension_ != NULL && |
| 2342 peek() == Token::FUNCTION && | 2349 peek() == Token::FUNCTION && |
| 2343 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2350 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2344 expr != NULL && | 2351 expr != NULL && |
| 2345 expr->AsVariableProxy() != NULL && | 2352 expr->AsVariableProxy() != NULL && |
| 2346 String::Equals(isolate()->factory()->native_string(), | 2353 expr->AsVariableProxy()->raw_name() == |
| 2347 expr->AsVariableProxy()->name()) && | 2354 ast_value_factory_->native_string() && |
| 2348 !scanner()->literal_contains_escapes()) { | 2355 !scanner()->literal_contains_escapes()) { |
| 2349 return ParseNativeDeclaration(ok); | 2356 return ParseNativeDeclaration(ok); |
| 2350 } | 2357 } |
| 2351 | 2358 |
| 2352 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2359 // Parsed expression statement, or the context-sensitive 'module' keyword. |
| 2353 // Only expect semicolon in the former case. | 2360 // Only expect semicolon in the former case. |
| 2354 if (!FLAG_harmony_modules || | 2361 if (!FLAG_harmony_modules || |
| 2355 peek() != Token::IDENTIFIER || | 2362 peek() != Token::IDENTIFIER || |
| 2356 scanner()->HasAnyLineTerminatorBeforeNext() || | 2363 scanner()->HasAnyLineTerminatorBeforeNext() || |
| 2357 expr->AsVariableProxy() == NULL || | 2364 expr->AsVariableProxy() == NULL || |
| 2358 !String::Equals(isolate()->factory()->module_string(), | 2365 expr->AsVariableProxy()->raw_name() != |
| 2359 expr->AsVariableProxy()->name()) || | 2366 ast_value_factory_->module_string() || |
| 2360 scanner()->literal_contains_escapes()) { | 2367 scanner()->literal_contains_escapes()) { |
| 2361 ExpectSemicolon(CHECK_OK); | 2368 ExpectSemicolon(CHECK_OK); |
| 2362 } | 2369 } |
| 2363 return factory()->NewExpressionStatement(expr, pos); | 2370 return factory()->NewExpressionStatement(expr, pos); |
| 2364 } | 2371 } |
| 2365 | 2372 |
| 2366 | 2373 |
| 2367 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2374 IfStatement* Parser::ParseIfStatement(ZoneList<const AstString*>* labels, |
| 2375 bool* ok) { |
| 2368 // IfStatement :: | 2376 // IfStatement :: |
| 2369 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2377 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2370 | 2378 |
| 2371 int pos = peek_position(); | 2379 int pos = peek_position(); |
| 2372 Expect(Token::IF, CHECK_OK); | 2380 Expect(Token::IF, CHECK_OK); |
| 2373 Expect(Token::LPAREN, CHECK_OK); | 2381 Expect(Token::LPAREN, CHECK_OK); |
| 2374 Expression* condition = ParseExpression(true, CHECK_OK); | 2382 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2375 Expect(Token::RPAREN, CHECK_OK); | 2383 Expect(Token::RPAREN, CHECK_OK); |
| 2376 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2384 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2377 Statement* else_statement = NULL; | 2385 Statement* else_statement = NULL; |
| 2378 if (peek() == Token::ELSE) { | 2386 if (peek() == Token::ELSE) { |
| 2379 Next(); | 2387 Next(); |
| 2380 else_statement = ParseStatement(labels, CHECK_OK); | 2388 else_statement = ParseStatement(labels, CHECK_OK); |
| 2381 } else { | 2389 } else { |
| 2382 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2390 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2383 } | 2391 } |
| 2384 return factory()->NewIfStatement( | 2392 return factory()->NewIfStatement( |
| 2385 condition, then_statement, else_statement, pos); | 2393 condition, then_statement, else_statement, pos); |
| 2386 } | 2394 } |
| 2387 | 2395 |
| 2388 | 2396 |
| 2389 Statement* Parser::ParseContinueStatement(bool* ok) { | 2397 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2390 // ContinueStatement :: | 2398 // ContinueStatement :: |
| 2391 // 'continue' Identifier? ';' | 2399 // 'continue' Identifier? ';' |
| 2392 | 2400 |
| 2393 int pos = peek_position(); | 2401 int pos = peek_position(); |
| 2394 Expect(Token::CONTINUE, CHECK_OK); | 2402 Expect(Token::CONTINUE, CHECK_OK); |
| 2395 Handle<String> label = Handle<String>::null(); | 2403 const AstString* label = NULL; |
| 2396 Token::Value tok = peek(); | 2404 Token::Value tok = peek(); |
| 2397 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2405 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2398 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2406 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2399 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2407 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2400 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2408 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2401 } | 2409 } |
| 2402 IterationStatement* target = NULL; | 2410 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); |
| 2403 target = LookupContinueTarget(label, CHECK_OK); | |
| 2404 if (target == NULL) { | 2411 if (target == NULL) { |
| 2405 // Illegal continue statement. | 2412 // Illegal continue statement. |
| 2406 const char* message = "illegal_continue"; | 2413 const char* message = "illegal_continue"; |
| 2407 if (!label.is_null()) { | 2414 if (label != NULL) { |
| 2408 message = "unknown_label"; | 2415 message = "unknown_label"; |
| 2409 } | 2416 } |
| 2410 ParserTraits::ReportMessage(message, label); | 2417 ParserTraits::ReportMessage(message, label); |
| 2411 *ok = false; | 2418 *ok = false; |
| 2412 return NULL; | 2419 return NULL; |
| 2413 } | 2420 } |
| 2414 ExpectSemicolon(CHECK_OK); | 2421 ExpectSemicolon(CHECK_OK); |
| 2415 return factory()->NewContinueStatement(target, pos); | 2422 return factory()->NewContinueStatement(target, pos); |
| 2416 } | 2423 } |
| 2417 | 2424 |
| 2418 | 2425 |
| 2419 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2426 Statement* Parser::ParseBreakStatement(ZoneList<const AstString*>* labels, |
| 2427 bool* ok) { |
| 2420 // BreakStatement :: | 2428 // BreakStatement :: |
| 2421 // 'break' Identifier? ';' | 2429 // 'break' Identifier? ';' |
| 2422 | 2430 |
| 2423 int pos = peek_position(); | 2431 int pos = peek_position(); |
| 2424 Expect(Token::BREAK, CHECK_OK); | 2432 Expect(Token::BREAK, CHECK_OK); |
| 2425 Handle<String> label; | 2433 const AstString* label = NULL; |
| 2426 Token::Value tok = peek(); | 2434 Token::Value tok = peek(); |
| 2427 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2435 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2428 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2436 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2429 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2437 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2430 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2438 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2431 } | 2439 } |
| 2432 // Parse labeled break statements that target themselves into | 2440 // Parse labeled break statements that target themselves into |
| 2433 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2441 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2434 if (!label.is_null() && ContainsLabel(labels, label)) { | 2442 if (label != NULL && ContainsLabel(labels, label)) { |
| 2435 ExpectSemicolon(CHECK_OK); | 2443 ExpectSemicolon(CHECK_OK); |
| 2436 return factory()->NewEmptyStatement(pos); | 2444 return factory()->NewEmptyStatement(pos); |
| 2437 } | 2445 } |
| 2438 BreakableStatement* target = NULL; | 2446 BreakableStatement* target = NULL; |
| 2439 target = LookupBreakTarget(label, CHECK_OK); | 2447 target = LookupBreakTarget(label, CHECK_OK); |
| 2440 if (target == NULL) { | 2448 if (target == NULL) { |
| 2441 // Illegal break statement. | 2449 // Illegal break statement. |
| 2442 const char* message = "illegal_break"; | 2450 const char* message = "illegal_break"; |
| 2443 if (!label.is_null()) { | 2451 if (label != NULL) { |
| 2444 message = "unknown_label"; | 2452 message = "unknown_label"; |
| 2445 } | 2453 } |
| 2446 ParserTraits::ReportMessage(message, label); | 2454 ParserTraits::ReportMessage(message, label); |
| 2447 *ok = false; | 2455 *ok = false; |
| 2448 return NULL; | 2456 return NULL; |
| 2449 } | 2457 } |
| 2450 ExpectSemicolon(CHECK_OK); | 2458 ExpectSemicolon(CHECK_OK); |
| 2451 return factory()->NewBreakStatement(target, pos); | 2459 return factory()->NewBreakStatement(target, pos); |
| 2452 } | 2460 } |
| 2453 | 2461 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2487 Scope* decl_scope = scope_->DeclarationScope(); | 2495 Scope* decl_scope = scope_->DeclarationScope(); |
| 2488 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { | 2496 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
| 2489 ReportMessageAt(loc, "illegal_return"); | 2497 ReportMessageAt(loc, "illegal_return"); |
| 2490 *ok = false; | 2498 *ok = false; |
| 2491 return NULL; | 2499 return NULL; |
| 2492 } | 2500 } |
| 2493 return result; | 2501 return result; |
| 2494 } | 2502 } |
| 2495 | 2503 |
| 2496 | 2504 |
| 2497 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2505 Statement* Parser::ParseWithStatement(ZoneList<const AstString*>* labels, |
| 2506 bool* ok) { |
| 2498 // WithStatement :: | 2507 // WithStatement :: |
| 2499 // 'with' '(' Expression ')' Statement | 2508 // 'with' '(' Expression ')' Statement |
| 2500 | 2509 |
| 2501 Expect(Token::WITH, CHECK_OK); | 2510 Expect(Token::WITH, CHECK_OK); |
| 2502 int pos = position(); | 2511 int pos = position(); |
| 2503 | 2512 |
| 2504 if (strict_mode() == STRICT) { | 2513 if (strict_mode() == STRICT) { |
| 2505 ReportMessage("strict_mode_with"); | 2514 ReportMessage("strict_mode_with"); |
| 2506 *ok = false; | 2515 *ok = false; |
| 2507 return NULL; | 2516 return NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2549 peek() != Token::DEFAULT && | 2558 peek() != Token::DEFAULT && |
| 2550 peek() != Token::RBRACE) { | 2559 peek() != Token::RBRACE) { |
| 2551 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2560 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2552 statements->Add(stat, zone()); | 2561 statements->Add(stat, zone()); |
| 2553 } | 2562 } |
| 2554 | 2563 |
| 2555 return factory()->NewCaseClause(label, statements, pos); | 2564 return factory()->NewCaseClause(label, statements, pos); |
| 2556 } | 2565 } |
| 2557 | 2566 |
| 2558 | 2567 |
| 2559 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2568 SwitchStatement* Parser::ParseSwitchStatement( |
| 2560 bool* ok) { | 2569 ZoneList<const AstString*>* labels, bool* ok) { |
| 2561 // SwitchStatement :: | 2570 // SwitchStatement :: |
| 2562 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2571 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2563 | 2572 |
| 2564 SwitchStatement* statement = | 2573 SwitchStatement* statement = |
| 2565 factory()->NewSwitchStatement(labels, peek_position()); | 2574 factory()->NewSwitchStatement(labels, peek_position()); |
| 2566 Target target(&this->target_stack_, statement); | 2575 Target target(&this->target_stack_, statement); |
| 2567 | 2576 |
| 2568 Expect(Token::SWITCH, CHECK_OK); | 2577 Expect(Token::SWITCH, CHECK_OK); |
| 2569 Expect(Token::LPAREN, CHECK_OK); | 2578 Expect(Token::LPAREN, CHECK_OK); |
| 2570 Expression* tag = ParseExpression(true, CHECK_OK); | 2579 Expression* tag = ParseExpression(true, CHECK_OK); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2633 } | 2642 } |
| 2634 | 2643 |
| 2635 // If we can break out from the catch block and there is a finally block, | 2644 // If we can break out from the catch block and there is a finally block, |
| 2636 // then we will need to collect escaping targets from the catch | 2645 // then we will need to collect escaping targets from the catch |
| 2637 // block. Since we don't know yet if there will be a finally block, we | 2646 // block. Since we don't know yet if there will be a finally block, we |
| 2638 // always collect the targets. | 2647 // always collect the targets. |
| 2639 TargetCollector catch_collector(zone()); | 2648 TargetCollector catch_collector(zone()); |
| 2640 Scope* catch_scope = NULL; | 2649 Scope* catch_scope = NULL; |
| 2641 Variable* catch_variable = NULL; | 2650 Variable* catch_variable = NULL; |
| 2642 Block* catch_block = NULL; | 2651 Block* catch_block = NULL; |
| 2643 Handle<String> name; | 2652 const AstString* name = NULL; |
| 2644 if (tok == Token::CATCH) { | 2653 if (tok == Token::CATCH) { |
| 2645 Consume(Token::CATCH); | 2654 Consume(Token::CATCH); |
| 2646 | 2655 |
| 2647 Expect(Token::LPAREN, CHECK_OK); | 2656 Expect(Token::LPAREN, CHECK_OK); |
| 2648 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2657 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2649 catch_scope->set_start_position(scanner()->location().beg_pos); | 2658 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2650 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2659 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2651 | 2660 |
| 2652 Expect(Token::RPAREN, CHECK_OK); | 2661 Expect(Token::RPAREN, CHECK_OK); |
| 2653 | 2662 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2703 index, try_block, finally_block, pos); | 2712 index, try_block, finally_block, pos); |
| 2704 // Combine the jump targets of the try block and the possible catch block. | 2713 // Combine the jump targets of the try block and the possible catch block. |
| 2705 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2714 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2706 } | 2715 } |
| 2707 | 2716 |
| 2708 result->set_escaping_targets(try_collector.targets()); | 2717 result->set_escaping_targets(try_collector.targets()); |
| 2709 return result; | 2718 return result; |
| 2710 } | 2719 } |
| 2711 | 2720 |
| 2712 | 2721 |
| 2713 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2722 DoWhileStatement* Parser::ParseDoWhileStatement( |
| 2714 bool* ok) { | 2723 ZoneList<const AstString*>* labels, bool* ok) { |
| 2715 // DoStatement :: | 2724 // DoStatement :: |
| 2716 // 'do' Statement 'while' '(' Expression ')' ';' | 2725 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2717 | 2726 |
| 2718 DoWhileStatement* loop = | 2727 DoWhileStatement* loop = |
| 2719 factory()->NewDoWhileStatement(labels, peek_position()); | 2728 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2720 Target target(&this->target_stack_, loop); | 2729 Target target(&this->target_stack_, loop); |
| 2721 | 2730 |
| 2722 Expect(Token::DO, CHECK_OK); | 2731 Expect(Token::DO, CHECK_OK); |
| 2723 Statement* body = ParseStatement(NULL, CHECK_OK); | 2732 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2724 Expect(Token::WHILE, CHECK_OK); | 2733 Expect(Token::WHILE, CHECK_OK); |
| 2725 Expect(Token::LPAREN, CHECK_OK); | 2734 Expect(Token::LPAREN, CHECK_OK); |
| 2726 | 2735 |
| 2727 Expression* cond = ParseExpression(true, CHECK_OK); | 2736 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2728 Expect(Token::RPAREN, CHECK_OK); | 2737 Expect(Token::RPAREN, CHECK_OK); |
| 2729 | 2738 |
| 2730 // Allow do-statements to be terminated with and without | 2739 // Allow do-statements to be terminated with and without |
| 2731 // semi-colons. This allows code such as 'do;while(0)return' to | 2740 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2732 // parse, which would not be the case if we had used the | 2741 // parse, which would not be the case if we had used the |
| 2733 // ExpectSemicolon() functionality here. | 2742 // ExpectSemicolon() functionality here. |
| 2734 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2743 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2735 | 2744 |
| 2736 if (loop != NULL) loop->Initialize(cond, body); | 2745 if (loop != NULL) loop->Initialize(cond, body); |
| 2737 return loop; | 2746 return loop; |
| 2738 } | 2747 } |
| 2739 | 2748 |
| 2740 | 2749 |
| 2741 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2750 WhileStatement* Parser::ParseWhileStatement(ZoneList<const AstString*>* labels, |
| 2751 bool* ok) { |
| 2742 // WhileStatement :: | 2752 // WhileStatement :: |
| 2743 // 'while' '(' Expression ')' Statement | 2753 // 'while' '(' Expression ')' Statement |
| 2744 | 2754 |
| 2745 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2755 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2746 Target target(&this->target_stack_, loop); | 2756 Target target(&this->target_stack_, loop); |
| 2747 | 2757 |
| 2748 Expect(Token::WHILE, CHECK_OK); | 2758 Expect(Token::WHILE, CHECK_OK); |
| 2749 Expect(Token::LPAREN, CHECK_OK); | 2759 Expect(Token::LPAREN, CHECK_OK); |
| 2750 Expression* cond = ParseExpression(true, CHECK_OK); | 2760 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2751 Expect(Token::RPAREN, CHECK_OK); | 2761 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2770 } | 2780 } |
| 2771 | 2781 |
| 2772 | 2782 |
| 2773 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2783 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2774 Expression* each, | 2784 Expression* each, |
| 2775 Expression* subject, | 2785 Expression* subject, |
| 2776 Statement* body) { | 2786 Statement* body) { |
| 2777 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2787 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2778 | 2788 |
| 2779 if (for_of != NULL) { | 2789 if (for_of != NULL) { |
| 2780 Factory* heap_factory = isolate()->factory(); | |
| 2781 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2790 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
| 2782 heap_factory->dot_iterator_string()); | 2791 ast_value_factory_->dot_iterator_string()); |
| 2783 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2792 Variable* result = scope_->DeclarationScope()->NewTemporary( |
| 2784 heap_factory->dot_result_string()); | 2793 ast_value_factory_->dot_result_string()); |
| 2785 | 2794 |
| 2786 Expression* assign_iterator; | 2795 Expression* assign_iterator; |
| 2787 Expression* next_result; | 2796 Expression* next_result; |
| 2788 Expression* result_done; | 2797 Expression* result_done; |
| 2789 Expression* assign_each; | 2798 Expression* assign_each; |
| 2790 | 2799 |
| 2791 // var iterator = iterable; | 2800 // var iterator = iterable; |
| 2792 { | 2801 { |
| 2793 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2802 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2794 assign_iterator = factory()->NewAssignment( | 2803 assign_iterator = factory()->NewAssignment( |
| 2795 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); | 2804 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
| 2796 } | 2805 } |
| 2797 | 2806 |
| 2798 // var result = iterator.next(); | 2807 // var result = iterator.next(); |
| 2799 { | 2808 { |
| 2800 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2809 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2801 Expression* next_literal = factory()->NewLiteral( | 2810 Expression* next_literal = factory()->NewStringLiteral( |
| 2802 heap_factory->next_string(), RelocInfo::kNoPosition); | 2811 ast_value_factory_->next_string(), RelocInfo::kNoPosition); |
| 2803 Expression* next_property = factory()->NewProperty( | 2812 Expression* next_property = factory()->NewProperty( |
| 2804 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2813 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| 2805 ZoneList<Expression*>* next_arguments = | 2814 ZoneList<Expression*>* next_arguments = |
| 2806 new(zone()) ZoneList<Expression*>(0, zone()); | 2815 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2807 Expression* next_call = factory()->NewCall( | 2816 Expression* next_call = factory()->NewCall( |
| 2808 next_property, next_arguments, RelocInfo::kNoPosition); | 2817 next_property, next_arguments, RelocInfo::kNoPosition); |
| 2809 Expression* result_proxy = factory()->NewVariableProxy(result); | 2818 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2810 next_result = factory()->NewAssignment( | 2819 next_result = factory()->NewAssignment( |
| 2811 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2820 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
| 2812 } | 2821 } |
| 2813 | 2822 |
| 2814 // result.done | 2823 // result.done |
| 2815 { | 2824 { |
| 2816 Expression* done_literal = factory()->NewLiteral( | 2825 Expression* done_literal = factory()->NewStringLiteral( |
| 2817 heap_factory->done_string(), RelocInfo::kNoPosition); | 2826 ast_value_factory_->done_string(), RelocInfo::kNoPosition); |
| 2818 Expression* result_proxy = factory()->NewVariableProxy(result); | 2827 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2819 result_done = factory()->NewProperty( | 2828 result_done = factory()->NewProperty( |
| 2820 result_proxy, done_literal, RelocInfo::kNoPosition); | 2829 result_proxy, done_literal, RelocInfo::kNoPosition); |
| 2821 } | 2830 } |
| 2822 | 2831 |
| 2823 // each = result.value | 2832 // each = result.value |
| 2824 { | 2833 { |
| 2825 Expression* value_literal = factory()->NewLiteral( | 2834 Expression* value_literal = factory()->NewStringLiteral( |
| 2826 heap_factory->value_string(), RelocInfo::kNoPosition); | 2835 ast_value_factory_->value_string(), RelocInfo::kNoPosition); |
| 2827 Expression* result_proxy = factory()->NewVariableProxy(result); | 2836 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2828 Expression* result_value = factory()->NewProperty( | 2837 Expression* result_value = factory()->NewProperty( |
| 2829 result_proxy, value_literal, RelocInfo::kNoPosition); | 2838 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 2830 assign_each = factory()->NewAssignment( | 2839 assign_each = factory()->NewAssignment( |
| 2831 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2840 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
| 2832 } | 2841 } |
| 2833 | 2842 |
| 2834 for_of->Initialize(each, subject, body, | 2843 for_of->Initialize(each, subject, body, |
| 2835 assign_iterator, next_result, result_done, assign_each); | 2844 assign_iterator, next_result, result_done, assign_each); |
| 2836 } else { | 2845 } else { |
| 2837 stmt->Initialize(each, subject, body); | 2846 stmt->Initialize(each, subject, body); |
| 2838 } | 2847 } |
| 2839 } | 2848 } |
| 2840 | 2849 |
| 2841 | 2850 |
| 2842 Statement* Parser::DesugarLetBindingsInForStatement( | 2851 Statement* Parser::DesugarLetBindingsInForStatement( |
| 2843 Scope* inner_scope, ZoneStringList* names, ForStatement* loop, | 2852 Scope* inner_scope, ZoneList<const AstString*>* names, |
| 2844 Statement* init, Expression* cond, Statement* next, Statement* body, | 2853 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| 2845 bool* ok) { | 2854 Statement* body, bool* ok) { |
| 2846 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are | 2855 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are |
| 2847 // copied into a new environment. After copying, the "next" statement of the | 2856 // copied into a new environment. After copying, the "next" statement of the |
| 2848 // loop is executed to update the loop variables. The loop condition is | 2857 // loop is executed to update the loop variables. The loop condition is |
| 2849 // checked and the loop body is executed. | 2858 // checked and the loop body is executed. |
| 2850 // | 2859 // |
| 2851 // We rewrite a for statement of the form | 2860 // We rewrite a for statement of the form |
| 2852 // | 2861 // |
| 2853 // for (let x = i; cond; next) body | 2862 // for (let x = i; cond; next) body |
| 2854 // | 2863 // |
| 2855 // into | 2864 // into |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2876 // } | 2885 // } |
| 2877 | 2886 |
| 2878 ASSERT(names->length() > 0); | 2887 ASSERT(names->length() > 0); |
| 2879 Scope* for_scope = scope_; | 2888 Scope* for_scope = scope_; |
| 2880 ZoneList<Variable*> temps(names->length(), zone()); | 2889 ZoneList<Variable*> temps(names->length(), zone()); |
| 2881 | 2890 |
| 2882 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, | 2891 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, |
| 2883 RelocInfo::kNoPosition); | 2892 RelocInfo::kNoPosition); |
| 2884 outer_block->AddStatement(init, zone()); | 2893 outer_block->AddStatement(init, zone()); |
| 2885 | 2894 |
| 2886 Handle<String> temp_name = isolate()->factory()->dot_for_string(); | 2895 const AstString* temp_name = ast_value_factory_->dot_for_string(); |
| 2887 Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate()); | |
| 2888 Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate()); | |
| 2889 | |
| 2890 | 2896 |
| 2891 // For each let variable x: | 2897 // For each let variable x: |
| 2892 // make statement: temp_x = x. | 2898 // make statement: temp_x = x. |
| 2893 for (int i = 0; i < names->length(); i++) { | 2899 for (int i = 0; i < names->length(); i++) { |
| 2894 VariableProxy* proxy = | 2900 VariableProxy* proxy = |
| 2895 NewUnresolved(names->at(i), LET, Interface::NewValue()); | 2901 NewUnresolved(names->at(i), LET, Interface::NewValue()); |
| 2896 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); | 2902 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); |
| 2897 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2903 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2898 Assignment* assignment = factory()->NewAssignment( | 2904 Assignment* assignment = factory()->NewAssignment( |
| 2899 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); | 2905 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); |
| 2900 Statement* assignment_statement = factory()->NewExpressionStatement( | 2906 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2901 assignment, RelocInfo::kNoPosition); | 2907 assignment, RelocInfo::kNoPosition); |
| 2902 outer_block->AddStatement(assignment_statement, zone()); | 2908 outer_block->AddStatement(assignment_statement, zone()); |
| 2903 temps.Add(temp, zone()); | 2909 temps.Add(temp, zone()); |
| 2904 } | 2910 } |
| 2905 | 2911 |
| 2906 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); | 2912 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); |
| 2907 // Make statement: flag = 1. | 2913 // Make statement: flag = 1. |
| 2908 { | 2914 { |
| 2909 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2915 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2910 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2916 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
| 2911 Assignment* assignment = factory()->NewAssignment( | 2917 Assignment* assignment = factory()->NewAssignment( |
| 2912 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); | 2918 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); |
| 2913 Statement* assignment_statement = factory()->NewExpressionStatement( | 2919 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2914 assignment, RelocInfo::kNoPosition); | 2920 assignment, RelocInfo::kNoPosition); |
| 2915 outer_block->AddStatement(assignment_statement, zone()); | 2921 outer_block->AddStatement(assignment_statement, zone()); |
| 2916 } | 2922 } |
| 2917 | 2923 |
| 2918 outer_block->AddStatement(loop, zone()); | 2924 outer_block->AddStatement(loop, zone()); |
| 2919 outer_block->set_scope(for_scope); | 2925 outer_block->set_scope(for_scope); |
| 2920 scope_ = inner_scope; | 2926 scope_ = inner_scope; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2940 assignment, pos); | 2946 assignment, pos); |
| 2941 proxy->var()->set_initializer_position(pos); | 2947 proxy->var()->set_initializer_position(pos); |
| 2942 inner_block->AddStatement(assignment_statement, zone()); | 2948 inner_block->AddStatement(assignment_statement, zone()); |
| 2943 } | 2949 } |
| 2944 | 2950 |
| 2945 // Make statement: if (flag == 1) { flag = 0; } else { next; }. | 2951 // Make statement: if (flag == 1) { flag = 0; } else { next; }. |
| 2946 { | 2952 { |
| 2947 Expression* compare = NULL; | 2953 Expression* compare = NULL; |
| 2948 // Make compare expresion: flag == 1. | 2954 // Make compare expresion: flag == 1. |
| 2949 { | 2955 { |
| 2950 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); | 2956 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
| 2951 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2957 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2952 compare = factory()->NewCompareOperation( | 2958 compare = factory()->NewCompareOperation( |
| 2953 Token::EQ, flag_proxy, const1, pos); | 2959 Token::EQ, flag_proxy, const1, pos); |
| 2954 } | 2960 } |
| 2955 Statement* clear_flag = NULL; | 2961 Statement* clear_flag = NULL; |
| 2956 // Make statement: flag = 0. | 2962 // Make statement: flag = 0. |
| 2957 { | 2963 { |
| 2958 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2964 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2959 Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition); | 2965 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); |
| 2960 Assignment* assignment = factory()->NewAssignment( | 2966 Assignment* assignment = factory()->NewAssignment( |
| 2961 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); | 2967 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); |
| 2962 clear_flag = factory()->NewExpressionStatement(assignment, pos); | 2968 clear_flag = factory()->NewExpressionStatement(assignment, pos); |
| 2963 } | 2969 } |
| 2964 Statement* clear_flag_or_next = factory()->NewIfStatement( | 2970 Statement* clear_flag_or_next = factory()->NewIfStatement( |
| 2965 compare, clear_flag, next, RelocInfo::kNoPosition); | 2971 compare, clear_flag, next, RelocInfo::kNoPosition); |
| 2966 inner_block->AddStatement(clear_flag_or_next, zone()); | 2972 inner_block->AddStatement(clear_flag_or_next, zone()); |
| 2967 } | 2973 } |
| 2968 | 2974 |
| 2969 | 2975 |
| 2970 // Make statement: if (cond) { } else { break; }. | 2976 // Make statement: if (cond) { } else { break; }. |
| 2971 { | 2977 { |
| 2972 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2978 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2973 BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK); | 2979 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); |
| 2974 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); | 2980 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); |
| 2975 Statement* if_not_cond_break = factory()->NewIfStatement( | 2981 Statement* if_not_cond_break = factory()->NewIfStatement( |
| 2976 cond, empty, stop, cond->position()); | 2982 cond, empty, stop, cond->position()); |
| 2977 inner_block->AddStatement(if_not_cond_break, zone()); | 2983 inner_block->AddStatement(if_not_cond_break, zone()); |
| 2978 } | 2984 } |
| 2979 | 2985 |
| 2980 inner_block->AddStatement(body, zone()); | 2986 inner_block->AddStatement(body, zone()); |
| 2981 | 2987 |
| 2982 // For each let variable x: | 2988 // For each let variable x: |
| 2983 // make statement: temp_x = x; | 2989 // make statement: temp_x = x; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2994 | 3000 |
| 2995 inner_scope->set_end_position(scanner()->location().end_pos); | 3001 inner_scope->set_end_position(scanner()->location().end_pos); |
| 2996 inner_block->set_scope(inner_scope); | 3002 inner_block->set_scope(inner_scope); |
| 2997 scope_ = for_scope; | 3003 scope_ = for_scope; |
| 2998 | 3004 |
| 2999 loop->Initialize(NULL, NULL, NULL, inner_block); | 3005 loop->Initialize(NULL, NULL, NULL, inner_block); |
| 3000 return outer_block; | 3006 return outer_block; |
| 3001 } | 3007 } |
| 3002 | 3008 |
| 3003 | 3009 |
| 3004 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 3010 Statement* Parser::ParseForStatement(ZoneList<const AstString*>* labels, |
| 3011 bool* ok) { |
| 3005 // ForStatement :: | 3012 // ForStatement :: |
| 3006 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3013 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 3007 | 3014 |
| 3008 int pos = peek_position(); | 3015 int pos = peek_position(); |
| 3009 Statement* init = NULL; | 3016 Statement* init = NULL; |
| 3010 ZoneStringList let_bindings(1, zone()); | 3017 ZoneList<const AstString*> let_bindings(1, zone()); |
| 3011 | 3018 |
| 3012 // Create an in-between scope for let-bound iteration variables. | 3019 // Create an in-between scope for let-bound iteration variables. |
| 3013 Scope* saved_scope = scope_; | 3020 Scope* saved_scope = scope_; |
| 3014 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3021 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3015 scope_ = for_scope; | 3022 scope_ = for_scope; |
| 3016 | 3023 |
| 3017 Expect(Token::FOR, CHECK_OK); | 3024 Expect(Token::FOR, CHECK_OK); |
| 3018 Expect(Token::LPAREN, CHECK_OK); | 3025 Expect(Token::LPAREN, CHECK_OK); |
| 3019 for_scope->set_start_position(scanner()->location().beg_pos); | 3026 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3020 if (peek() != Token::SEMICOLON) { | 3027 if (peek() != Token::SEMICOLON) { |
| 3021 if (peek() == Token::VAR || peek() == Token::CONST) { | 3028 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 3022 bool is_const = peek() == Token::CONST; | 3029 bool is_const = peek() == Token::CONST; |
| 3023 Handle<String> name; | 3030 const AstString* name = NULL; |
| 3024 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3031 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3025 Block* variable_statement = | 3032 Block* variable_statement = |
| 3026 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3033 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 3027 CHECK_OK); | 3034 CHECK_OK); |
| 3028 bool accept_OF = decl_props == kHasNoInitializers; | 3035 bool accept_OF = decl_props == kHasNoInitializers; |
| 3029 ForEachStatement::VisitMode mode; | 3036 ForEachStatement::VisitMode mode; |
| 3030 | 3037 |
| 3031 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 3038 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { |
| 3032 Interface* interface = | 3039 Interface* interface = |
| 3033 is_const ? Interface::NewConst() : Interface::NewValue(); | 3040 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 3034 ForEachStatement* loop = | 3041 ForEachStatement* loop = |
| 3035 factory()->NewForEachStatement(mode, labels, pos); | 3042 factory()->NewForEachStatement(mode, labels, pos); |
| 3036 Target target(&this->target_stack_, loop); | 3043 Target target(&this->target_stack_, loop); |
| 3037 | 3044 |
| 3038 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3045 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3039 Expect(Token::RPAREN, CHECK_OK); | 3046 Expect(Token::RPAREN, CHECK_OK); |
| 3040 | 3047 |
| 3041 VariableProxy* each = | 3048 VariableProxy* each = |
| 3042 scope_->NewUnresolved(factory(), name, interface); | 3049 scope_->NewUnresolved(factory(), name, interface); |
| 3043 Statement* body = ParseStatement(NULL, CHECK_OK); | 3050 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 3044 InitializeForEachStatement(loop, each, enumerable, body); | 3051 InitializeForEachStatement(loop, each, enumerable, body); |
| 3045 Block* result = | 3052 Block* result = |
| 3046 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3053 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3047 result->AddStatement(variable_statement, zone()); | 3054 result->AddStatement(variable_statement, zone()); |
| 3048 result->AddStatement(loop, zone()); | 3055 result->AddStatement(loop, zone()); |
| 3049 scope_ = saved_scope; | 3056 scope_ = saved_scope; |
| 3050 for_scope->set_end_position(scanner()->location().end_pos); | 3057 for_scope->set_end_position(scanner()->location().end_pos); |
| 3051 for_scope = for_scope->FinalizeBlockScope(); | 3058 for_scope = for_scope->FinalizeBlockScope(); |
| 3052 ASSERT(for_scope == NULL); | 3059 ASSERT(for_scope == NULL); |
| 3053 // Parsed for-in loop w/ variable/const declaration. | 3060 // Parsed for-in loop w/ variable/const declaration. |
| 3054 return result; | 3061 return result; |
| 3055 } else { | 3062 } else { |
| 3056 init = variable_statement; | 3063 init = variable_statement; |
| 3057 } | 3064 } |
| 3058 } else if (peek() == Token::LET) { | 3065 } else if (peek() == Token::LET) { |
| 3059 Handle<String> name; | 3066 const AstString* name = NULL; |
| 3060 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3067 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3061 Block* variable_statement = | 3068 Block* variable_statement = |
| 3062 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3069 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3063 &name, CHECK_OK); | 3070 &name, CHECK_OK); |
| 3064 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 3071 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 3065 bool accept_OF = decl_props == kHasNoInitializers; | 3072 bool accept_OF = decl_props == kHasNoInitializers; |
| 3066 ForEachStatement::VisitMode mode; | 3073 ForEachStatement::VisitMode mode; |
| 3067 | 3074 |
| 3068 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3075 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
| 3069 // Rewrite a for-in statement of the form | 3076 // Rewrite a for-in statement of the form |
| 3070 // | 3077 // |
| 3071 // for (let x in e) b | 3078 // for (let x in e) b |
| 3072 // | 3079 // |
| 3073 // into | 3080 // into |
| 3074 // | 3081 // |
| 3075 // <let x' be a temporary variable> | 3082 // <let x' be a temporary variable> |
| 3076 // for (x' in e) { | 3083 // for (x' in e) { |
| 3077 // let x; | 3084 // let x; |
| 3078 // x = x'; | 3085 // x = x'; |
| 3079 // b; | 3086 // b; |
| 3080 // } | 3087 // } |
| 3081 | 3088 |
| 3082 // TODO(keuchel): Move the temporary variable to the block scope, after | 3089 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 3083 // implementing stack allocated block scoped variables. | 3090 // implementing stack allocated block scoped variables. |
| 3084 Factory* heap_factory = isolate()->factory(); | 3091 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 3085 Handle<String> tempstr; | 3092 ast_value_factory_->dot_for_string()); |
| 3086 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 3087 isolate(), tempstr, | |
| 3088 heap_factory->NewConsString(heap_factory->dot_for_string(), name), | |
| 3089 0); | |
| 3090 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | |
| 3091 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); | |
| 3092 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3093 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 3093 ForEachStatement* loop = | 3094 ForEachStatement* loop = |
| 3094 factory()->NewForEachStatement(mode, labels, pos); | 3095 factory()->NewForEachStatement(mode, labels, pos); |
| 3095 Target target(&this->target_stack_, loop); | 3096 Target target(&this->target_stack_, loop); |
| 3096 | 3097 |
| 3097 // The expression does not see the loop variable. | 3098 // The expression does not see the loop variable. |
| 3098 scope_ = saved_scope; | 3099 scope_ = saved_scope; |
| 3099 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3100 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3100 scope_ = for_scope; | 3101 scope_ = for_scope; |
| 3101 Expect(Token::RPAREN, CHECK_OK); | 3102 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3212 // DebuggerStatement :: | 3213 // DebuggerStatement :: |
| 3213 // 'debugger' ';' | 3214 // 'debugger' ';' |
| 3214 | 3215 |
| 3215 int pos = peek_position(); | 3216 int pos = peek_position(); |
| 3216 Expect(Token::DEBUGGER, CHECK_OK); | 3217 Expect(Token::DEBUGGER, CHECK_OK); |
| 3217 ExpectSemicolon(CHECK_OK); | 3218 ExpectSemicolon(CHECK_OK); |
| 3218 return factory()->NewDebuggerStatement(pos); | 3219 return factory()->NewDebuggerStatement(pos); |
| 3219 } | 3220 } |
| 3220 | 3221 |
| 3221 | 3222 |
| 3222 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { | 3223 void Parser::ReportInvalidCachedData(const AstString* name, bool* ok) { |
| 3223 ParserTraits::ReportMessage("invalid_cached_data_function", name); | 3224 ParserTraits::ReportMessage("invalid_cached_data_function", name); |
| 3224 *ok = false; | 3225 *ok = false; |
| 3225 } | 3226 } |
| 3226 | 3227 |
| 3227 | 3228 |
| 3228 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3229 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3229 if (expression->IsLiteral()) return true; | 3230 if (expression->IsLiteral()) return true; |
| 3230 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3231 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3231 return lit != NULL && lit->is_simple(); | 3232 return lit != NULL && lit->is_simple(); |
| 3232 } | 3233 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3262 return static_cast<LiteralType>(literal_type->value()); | 3263 return static_cast<LiteralType>(literal_type->value()); |
| 3263 } | 3264 } |
| 3264 | 3265 |
| 3265 | 3266 |
| 3266 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3267 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| 3267 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3268 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
| 3268 } | 3269 } |
| 3269 | 3270 |
| 3270 | 3271 |
| 3271 FunctionLiteral* Parser::ParseFunctionLiteral( | 3272 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3272 Handle<String> function_name, | 3273 const AstString* function_name, |
| 3273 Scanner::Location function_name_location, | 3274 Scanner::Location function_name_location, |
| 3274 bool name_is_strict_reserved, | 3275 bool name_is_strict_reserved, |
| 3275 bool is_generator, | 3276 bool is_generator, |
| 3276 int function_token_pos, | 3277 int function_token_pos, |
| 3277 FunctionLiteral::FunctionType function_type, | 3278 FunctionLiteral::FunctionType function_type, |
| 3278 bool* ok) { | 3279 bool* ok) { |
| 3279 // Function :: | 3280 // Function :: |
| 3280 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3281 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3281 | 3282 |
| 3282 int pos = function_token_pos == RelocInfo::kNoPosition | 3283 int pos = function_token_pos == RelocInfo::kNoPosition |
| 3283 ? peek_position() : function_token_pos; | 3284 ? peek_position() : function_token_pos; |
| 3284 | 3285 |
| 3285 // Anonymous functions were passed either the empty symbol or a null | 3286 // Anonymous functions were passed either the empty symbol or a null |
| 3286 // handle as the function name. Remember if we were passed a non-empty | 3287 // handle as the function name. Remember if we were passed a non-empty |
| 3287 // handle to decide whether to invoke function name inference. | 3288 // handle to decide whether to invoke function name inference. |
| 3288 bool should_infer_name = function_name.is_null(); | 3289 bool should_infer_name = function_name == NULL; |
| 3289 | 3290 |
| 3290 // We want a non-null handle as the function name. | 3291 // We want a non-null handle as the function name. |
| 3291 if (should_infer_name) { | 3292 if (should_infer_name) { |
| 3292 function_name = isolate()->factory()->empty_string(); | 3293 function_name = ast_value_factory_->empty_string(); |
| 3293 } | 3294 } |
| 3294 | 3295 |
| 3295 int num_parameters = 0; | 3296 int num_parameters = 0; |
| 3296 // Function declarations are function scoped in normal mode, so they are | 3297 // Function declarations are function scoped in normal mode, so they are |
| 3297 // hoisted. In harmony block scoping mode they are block scoped, so they | 3298 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3298 // are not hoisted. | 3299 // are not hoisted. |
| 3299 // | 3300 // |
| 3300 // One tricky case are function declarations in a local sloppy-mode eval: | 3301 // One tricky case are function declarations in a local sloppy-mode eval: |
| 3301 // their declaration is hoisted, but they still see the local scope. E.g., | 3302 // their declaration is hoisted, but they still see the local scope. E.g., |
| 3302 // | 3303 // |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3334 int expected_property_count = -1; | 3335 int expected_property_count = -1; |
| 3335 int handler_count = 0; | 3336 int handler_count = 0; |
| 3336 FunctionLiteral::ParameterFlag duplicate_parameters = | 3337 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3337 FunctionLiteral::kNoDuplicateParameters; | 3338 FunctionLiteral::kNoDuplicateParameters; |
| 3338 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3339 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 3339 ? FunctionLiteral::kIsParenthesized | 3340 ? FunctionLiteral::kIsParenthesized |
| 3340 : FunctionLiteral::kNotParenthesized; | 3341 : FunctionLiteral::kNotParenthesized; |
| 3341 AstProperties ast_properties; | 3342 AstProperties ast_properties; |
| 3342 BailoutReason dont_optimize_reason = kNoReason; | 3343 BailoutReason dont_optimize_reason = kNoReason; |
| 3343 // Parse function body. | 3344 // Parse function body. |
| 3344 { FunctionState function_state(&function_state_, &scope_, scope, zone()); | 3345 { |
| 3346 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 3347 ast_value_factory_); |
| 3345 scope_->SetScopeName(function_name); | 3348 scope_->SetScopeName(function_name); |
| 3346 | 3349 |
| 3347 if (is_generator) { | 3350 if (is_generator) { |
| 3348 // For generators, allocating variables in contexts is currently a win | 3351 // For generators, allocating variables in contexts is currently a win |
| 3349 // because it minimizes the work needed to suspend and resume an | 3352 // because it minimizes the work needed to suspend and resume an |
| 3350 // activation. | 3353 // activation. |
| 3351 scope_->ForceContextAllocation(); | 3354 scope_->ForceContextAllocation(); |
| 3352 | 3355 |
| 3353 // Calling a generator returns a generator object. That object is stored | 3356 // Calling a generator returns a generator object. That object is stored |
| 3354 // in a temporary variable, a definition that is used by "yield" | 3357 // in a temporary variable, a definition that is used by "yield" |
| 3355 // expressions. This also marks the FunctionState as a generator. | 3358 // expressions. This also marks the FunctionState as a generator. |
| 3356 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3359 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 3357 isolate()->factory()->dot_generator_object_string()); | 3360 ast_value_factory_->dot_generator_object_string()); |
| 3358 function_state.set_generator_object_variable(temp); | 3361 function_state.set_generator_object_variable(temp); |
| 3359 } | 3362 } |
| 3360 | 3363 |
| 3361 // FormalParameterList :: | 3364 // FormalParameterList :: |
| 3362 // '(' (Identifier)*[','] ')' | 3365 // '(' (Identifier)*[','] ')' |
| 3363 Expect(Token::LPAREN, CHECK_OK); | 3366 Expect(Token::LPAREN, CHECK_OK); |
| 3364 scope->set_start_position(scanner()->location().beg_pos); | 3367 scope->set_start_position(scanner()->location().beg_pos); |
| 3365 | 3368 |
| 3366 // We don't yet know if the function will be strict, so we cannot yet | 3369 // We don't yet know if the function will be strict, so we cannot yet |
| 3367 // produce errors for parameter names or duplicates. However, we remember | 3370 // produce errors for parameter names or duplicates. However, we remember |
| 3368 // the locations of these errors if they occur and produce the errors later. | 3371 // the locations of these errors if they occur and produce the errors later. |
| 3369 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3372 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 3370 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3373 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 3371 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3374 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3372 | 3375 |
| 3373 bool done = (peek() == Token::RPAREN); | 3376 bool done = (peek() == Token::RPAREN); |
| 3374 while (!done) { | 3377 while (!done) { |
| 3375 bool is_strict_reserved = false; | 3378 bool is_strict_reserved = false; |
| 3376 Handle<String> param_name = | 3379 const AstString* param_name = |
| 3377 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3380 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3378 | 3381 |
| 3379 // Store locations for possible future error reports. | 3382 // Store locations for possible future error reports. |
| 3380 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3383 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 3381 eval_args_error_log = scanner()->location(); | 3384 eval_args_error_log = scanner()->location(); |
| 3382 } | 3385 } |
| 3383 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3386 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3384 reserved_loc = scanner()->location(); | 3387 reserved_loc = scanner()->location(); |
| 3385 } | 3388 } |
| 3386 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3389 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3410 // instead of Variables and Proxis as is the case now. | 3413 // instead of Variables and Proxis as is the case now. |
| 3411 Variable* fvar = NULL; | 3414 Variable* fvar = NULL; |
| 3412 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3415 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3413 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3416 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3414 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3417 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3415 fvar_init_op = Token::INIT_CONST; | 3418 fvar_init_op = Token::INIT_CONST; |
| 3416 } | 3419 } |
| 3417 VariableMode fvar_mode = | 3420 VariableMode fvar_mode = |
| 3418 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3421 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
| 3419 : CONST_LEGACY; | 3422 : CONST_LEGACY; |
| 3423 ASSERT(function_name != NULL); |
| 3420 fvar = new(zone()) Variable(scope_, | 3424 fvar = new(zone()) Variable(scope_, |
| 3421 function_name, fvar_mode, true /* is valid LHS */, | 3425 function_name, fvar_mode, true /* is valid LHS */, |
| 3422 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3426 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3423 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3427 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3424 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3428 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3425 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3429 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3426 scope_->DeclareFunctionVar(fvar_declaration); | 3430 scope_->DeclareFunctionVar(fvar_declaration); |
| 3427 } | 3431 } |
| 3428 | 3432 |
| 3429 // Determine if the function can be parsed lazily. Lazy parsing is different | 3433 // Determine if the function can be parsed lazily. Lazy parsing is different |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3513 | 3517 |
| 3514 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3518 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3515 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3519 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3516 } | 3520 } |
| 3517 | 3521 |
| 3518 FunctionLiteral::IsGeneratorFlag generator = is_generator | 3522 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 3519 ? FunctionLiteral::kIsGenerator | 3523 ? FunctionLiteral::kIsGenerator |
| 3520 : FunctionLiteral::kNotGenerator; | 3524 : FunctionLiteral::kNotGenerator; |
| 3521 FunctionLiteral* function_literal = | 3525 FunctionLiteral* function_literal = |
| 3522 factory()->NewFunctionLiteral(function_name, | 3526 factory()->NewFunctionLiteral(function_name, |
| 3527 ast_value_factory_, |
| 3523 scope, | 3528 scope, |
| 3524 body, | 3529 body, |
| 3525 materialized_literal_count, | 3530 materialized_literal_count, |
| 3526 expected_property_count, | 3531 expected_property_count, |
| 3527 handler_count, | 3532 handler_count, |
| 3528 num_parameters, | 3533 num_parameters, |
| 3529 duplicate_parameters, | 3534 duplicate_parameters, |
| 3530 function_type, | 3535 function_type, |
| 3531 FunctionLiteral::kIsFunction, | 3536 FunctionLiteral::kIsFunction, |
| 3532 parenthesized, | 3537 parenthesized, |
| 3533 generator, | 3538 generator, |
| 3534 pos); | 3539 pos); |
| 3535 function_literal->set_function_token_position(function_token_pos); | 3540 function_literal->set_function_token_position(function_token_pos); |
| 3536 function_literal->set_ast_properties(&ast_properties); | 3541 function_literal->set_ast_properties(&ast_properties); |
| 3537 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3542 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 3538 | 3543 |
| 3539 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3544 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3540 return function_literal; | 3545 return function_literal; |
| 3541 } | 3546 } |
| 3542 | 3547 |
| 3543 | 3548 |
| 3544 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3549 void Parser::SkipLazyFunctionBody(const AstString* function_name, |
| 3545 int* materialized_literal_count, | 3550 int* materialized_literal_count, |
| 3546 int* expected_property_count, | 3551 int* expected_property_count, |
| 3547 bool* ok) { | 3552 bool* ok) { |
| 3548 int function_block_pos = position(); | 3553 int function_block_pos = position(); |
| 3549 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3554 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 3550 // If we have cached data, we use it to skip parsing the function body. The | 3555 // If we have cached data, we use it to skip parsing the function body. The |
| 3551 // data contains the information we need to construct the lazy function. | 3556 // data contains the information we need to construct the lazy function. |
| 3552 FunctionEntry entry = | 3557 FunctionEntry entry = |
| 3553 (*cached_data())->GetFunctionEntry(function_block_pos); | 3558 (*cached_data())->GetFunctionEntry(function_block_pos); |
| 3554 if (entry.is_valid()) { | 3559 if (entry.is_valid()) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3613 log_->LogFunction(function_block_pos, body_end, | 3618 log_->LogFunction(function_block_pos, body_end, |
| 3614 *materialized_literal_count, | 3619 *materialized_literal_count, |
| 3615 *expected_property_count, | 3620 *expected_property_count, |
| 3616 scope_->strict_mode()); | 3621 scope_->strict_mode()); |
| 3617 } | 3622 } |
| 3618 } | 3623 } |
| 3619 } | 3624 } |
| 3620 | 3625 |
| 3621 | 3626 |
| 3622 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3627 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3623 Handle<String> function_name, int pos, Variable* fvar, | 3628 const AstString* function_name, int pos, Variable* fvar, |
| 3624 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3629 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3625 // Everything inside an eagerly parsed function will be parsed eagerly | 3630 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3626 // (see comment above). | 3631 // (see comment above). |
| 3627 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3632 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 3628 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3633 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3629 if (fvar != NULL) { | 3634 if (fvar != NULL) { |
| 3630 VariableProxy* fproxy = scope_->NewUnresolved( | 3635 VariableProxy* fproxy = scope_->NewUnresolved( |
| 3631 factory(), function_name, Interface::NewConst()); | 3636 factory(), function_name, Interface::NewConst()); |
| 3632 fproxy->BindTo(fvar); | 3637 fproxy->BindTo(fvar); |
| 3633 body->Add(factory()->NewExpressionStatement( | 3638 body->Add(factory()->NewExpressionStatement( |
| 3634 factory()->NewAssignment(fvar_init_op, | 3639 factory()->NewAssignment(fvar_init_op, |
| 3635 fproxy, | 3640 fproxy, |
| 3636 factory()->NewThisFunction(pos), | 3641 factory()->NewThisFunction(pos), |
| 3637 RelocInfo::kNoPosition), | 3642 RelocInfo::kNoPosition), |
| 3638 RelocInfo::kNoPosition), zone()); | 3643 RelocInfo::kNoPosition), zone()); |
| 3639 } | 3644 } |
| 3640 | 3645 |
| 3641 // For generators, allocate and yield an iterator on function entry. | 3646 // For generators, allocate and yield an iterator on function entry. |
| 3642 if (is_generator) { | 3647 if (is_generator) { |
| 3643 ZoneList<Expression*>* arguments = | 3648 ZoneList<Expression*>* arguments = |
| 3644 new(zone()) ZoneList<Expression*>(0, zone()); | 3649 new(zone()) ZoneList<Expression*>(0, zone()); |
| 3645 CallRuntime* allocation = factory()->NewCallRuntime( | 3650 CallRuntime* allocation = factory()->NewCallRuntime( |
| 3646 isolate()->factory()->empty_string(), | 3651 ast_value_factory_->empty_string(), |
| 3647 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), | 3652 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
| 3648 arguments, pos); | 3653 arguments, pos); |
| 3649 VariableProxy* init_proxy = factory()->NewVariableProxy( | 3654 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 3650 function_state_->generator_object_variable()); | 3655 function_state_->generator_object_variable()); |
| 3651 Assignment* assignment = factory()->NewAssignment( | 3656 Assignment* assignment = factory()->NewAssignment( |
| 3652 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3657 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 3653 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3658 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3654 function_state_->generator_object_variable()); | 3659 function_state_->generator_object_variable()); |
| 3655 Yield* yield = factory()->NewYield( | 3660 Yield* yield = factory()->NewYield( |
| 3656 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 3661 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 3657 body->Add(factory()->NewExpressionStatement( | 3662 body->Add(factory()->NewExpressionStatement( |
| 3658 yield, RelocInfo::kNoPosition), zone()); | 3663 yield, RelocInfo::kNoPosition), zone()); |
| 3659 } | 3664 } |
| 3660 | 3665 |
| 3661 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 3666 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 3662 | 3667 |
| 3663 if (is_generator) { | 3668 if (is_generator) { |
| 3664 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3669 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3665 function_state_->generator_object_variable()); | 3670 function_state_->generator_object_variable()); |
| 3666 Expression *undefined = factory()->NewLiteral( | 3671 Expression* undefined = |
| 3667 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 3672 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
| 3668 Yield* yield = factory()->NewYield( | 3673 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL, |
| 3669 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 3674 RelocInfo::kNoPosition); |
| 3670 body->Add(factory()->NewExpressionStatement( | 3675 body->Add(factory()->NewExpressionStatement( |
| 3671 yield, RelocInfo::kNoPosition), zone()); | 3676 yield, RelocInfo::kNoPosition), zone()); |
| 3672 } | 3677 } |
| 3673 | 3678 |
| 3674 Expect(Token::RBRACE, CHECK_OK); | 3679 Expect(Token::RBRACE, CHECK_OK); |
| 3675 scope_->set_end_position(scanner()->location().end_pos); | 3680 scope_->set_end_position(scanner()->location().end_pos); |
| 3676 | 3681 |
| 3677 return body; | 3682 return body; |
| 3678 } | 3683 } |
| 3679 | 3684 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3703 } | 3708 } |
| 3704 | 3709 |
| 3705 | 3710 |
| 3706 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3711 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3707 // CallRuntime :: | 3712 // CallRuntime :: |
| 3708 // '%' Identifier Arguments | 3713 // '%' Identifier Arguments |
| 3709 | 3714 |
| 3710 int pos = peek_position(); | 3715 int pos = peek_position(); |
| 3711 Expect(Token::MOD, CHECK_OK); | 3716 Expect(Token::MOD, CHECK_OK); |
| 3712 // Allow "eval" or "arguments" for backward compatibility. | 3717 // Allow "eval" or "arguments" for backward compatibility. |
| 3713 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3718 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3714 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3719 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3715 | 3720 |
| 3716 if (extension_ != NULL) { | 3721 if (extension_ != NULL) { |
| 3717 // The extension structures are only accessible while parsing the | 3722 // The extension structures are only accessible while parsing the |
| 3718 // very first time not when reparsing because of lazy compilation. | 3723 // very first time not when reparsing because of lazy compilation. |
| 3719 scope_->DeclarationScope()->ForceEagerCompilation(); | 3724 scope_->DeclarationScope()->ForceEagerCompilation(); |
| 3720 } | 3725 } |
| 3721 | 3726 |
| 3722 const Runtime::Function* function = Runtime::FunctionForName(name); | 3727 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
| 3723 | 3728 |
| 3724 // Check for built-in IS_VAR macro. | 3729 // Check for built-in IS_VAR macro. |
| 3725 if (function != NULL && | 3730 if (function != NULL && |
| 3726 function->intrinsic_type == Runtime::RUNTIME && | 3731 function->intrinsic_type == Runtime::RUNTIME && |
| 3727 function->function_id == Runtime::kIS_VAR) { | 3732 function->function_id == Runtime::kIS_VAR) { |
| 3728 // %IS_VAR(x) evaluates to x if x is a variable, | 3733 // %IS_VAR(x) evaluates to x if x is a variable, |
| 3729 // leads to a parse error otherwise. Could be implemented as an | 3734 // leads to a parse error otherwise. Could be implemented as an |
| 3730 // inline function %_IS_VAR(x) to eliminate this special case. | 3735 // inline function %_IS_VAR(x) to eliminate this special case. |
| 3731 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | 3736 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
| 3732 return args->at(0); | 3737 return args->at(0); |
| 3733 } else { | 3738 } else { |
| 3734 ReportMessage("not_isvar"); | 3739 ReportMessage("not_isvar"); |
| 3735 *ok = false; | 3740 *ok = false; |
| 3736 return NULL; | 3741 return NULL; |
| 3737 } | 3742 } |
| 3738 } | 3743 } |
| 3739 | 3744 |
| 3740 // Check that the expected number of arguments are being passed. | 3745 // Check that the expected number of arguments are being passed. |
| 3741 if (function != NULL && | 3746 if (function != NULL && |
| 3742 function->nargs != -1 && | 3747 function->nargs != -1 && |
| 3743 function->nargs != args->length()) { | 3748 function->nargs != args->length()) { |
| 3744 ReportMessage("illegal_access"); | 3749 ReportMessage("illegal_access"); |
| 3745 *ok = false; | 3750 *ok = false; |
| 3746 return NULL; | 3751 return NULL; |
| 3747 } | 3752 } |
| 3748 | 3753 |
| 3749 // Check that the function is defined if it's an inline runtime call. | 3754 // Check that the function is defined if it's an inline runtime call. |
| 3750 if (function == NULL && name->Get(0) == '_') { | 3755 if (function == NULL && name->FirstCharacter() == '_') { |
| 3751 ParserTraits::ReportMessage("not_defined", name); | 3756 ParserTraits::ReportMessage("not_defined", name); |
| 3752 *ok = false; | 3757 *ok = false; |
| 3753 return NULL; | 3758 return NULL; |
| 3754 } | 3759 } |
| 3755 | 3760 |
| 3756 // We have a valid intrinsics call or a call to a builtin. | 3761 // We have a valid intrinsics call or a call to a builtin. |
| 3757 return factory()->NewCallRuntime(name, function, args, pos); | 3762 return factory()->NewCallRuntime(name, function, args, pos); |
| 3758 } | 3763 } |
| 3759 | 3764 |
| 3760 | 3765 |
| 3761 Literal* Parser::GetLiteralUndefined(int position) { | 3766 Literal* Parser::GetLiteralUndefined(int position) { |
| 3762 return factory()->NewLiteral( | 3767 return factory()->NewUndefinedLiteral(position); |
| 3763 isolate()->factory()->undefined_value(), position); | |
| 3764 } | 3768 } |
| 3765 | 3769 |
| 3766 | 3770 |
| 3767 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3771 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 3768 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3772 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 3769 if (decl != NULL) { | 3773 if (decl != NULL) { |
| 3770 // In harmony mode we treat conflicting variable bindinds as early | 3774 // In harmony mode we treat conflicting variable bindinds as early |
| 3771 // errors. See ES5 16 for a definition of early errors. | 3775 // errors. See ES5 16 for a definition of early errors. |
| 3772 Handle<String> name = decl->proxy()->name(); | 3776 const AstString* name = decl->proxy()->raw_name(); |
| 3773 int position = decl->proxy()->position(); | 3777 int position = decl->proxy()->position(); |
| 3774 Scanner::Location location = position == RelocInfo::kNoPosition | 3778 Scanner::Location location = position == RelocInfo::kNoPosition |
| 3775 ? Scanner::Location::invalid() | 3779 ? Scanner::Location::invalid() |
| 3776 : Scanner::Location(position, position + 1); | 3780 : Scanner::Location(position, position + 1); |
| 3777 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 3781 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
| 3778 *ok = false; | 3782 *ok = false; |
| 3779 } | 3783 } |
| 3780 } | 3784 } |
| 3781 | 3785 |
| 3782 | 3786 |
| 3783 // ---------------------------------------------------------------------------- | 3787 // ---------------------------------------------------------------------------- |
| 3784 // Parser support | 3788 // Parser support |
| 3785 | 3789 |
| 3786 | 3790 |
| 3787 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3791 bool Parser::TargetStackContainsLabel(const AstString* label) { |
| 3788 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3792 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3789 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3793 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3790 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 3794 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 3791 return true; | 3795 return true; |
| 3792 } | 3796 } |
| 3793 return false; | 3797 return false; |
| 3794 } | 3798 } |
| 3795 | 3799 |
| 3796 | 3800 |
| 3797 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { | 3801 BreakableStatement* Parser::LookupBreakTarget(const AstString* label, |
| 3798 bool anonymous = label.is_null(); | 3802 bool* ok) { |
| 3803 bool anonymous = label == NULL; |
| 3799 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3804 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3800 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3805 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3801 if (stat == NULL) continue; | 3806 if (stat == NULL) continue; |
| 3802 if ((anonymous && stat->is_target_for_anonymous()) || | 3807 if ((anonymous && stat->is_target_for_anonymous()) || |
| 3803 (!anonymous && ContainsLabel(stat->labels(), label))) { | 3808 (!anonymous && ContainsLabel(stat->labels(), label))) { |
| 3804 RegisterTargetUse(stat->break_target(), t->previous()); | 3809 RegisterTargetUse(stat->break_target(), t->previous()); |
| 3805 return stat; | 3810 return stat; |
| 3806 } | 3811 } |
| 3807 } | 3812 } |
| 3808 return NULL; | 3813 return NULL; |
| 3809 } | 3814 } |
| 3810 | 3815 |
| 3811 | 3816 |
| 3812 IterationStatement* Parser::LookupContinueTarget(Handle<String> label, | 3817 IterationStatement* Parser::LookupContinueTarget(const AstString* label, |
| 3813 bool* ok) { | 3818 bool* ok) { |
| 3814 bool anonymous = label.is_null(); | 3819 bool anonymous = label == NULL; |
| 3815 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3820 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3816 IterationStatement* stat = t->node()->AsIterationStatement(); | 3821 IterationStatement* stat = t->node()->AsIterationStatement(); |
| 3817 if (stat == NULL) continue; | 3822 if (stat == NULL) continue; |
| 3818 | 3823 |
| 3819 ASSERT(stat->is_target_for_anonymous()); | 3824 ASSERT(stat->is_target_for_anonymous()); |
| 3820 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3825 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 3821 RegisterTargetUse(stat->continue_target(), t->previous()); | 3826 RegisterTargetUse(stat->continue_target(), t->previous()); |
| 3822 return stat; | 3827 return stat; |
| 3823 } | 3828 } |
| 3824 } | 3829 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3837 } | 3842 } |
| 3838 | 3843 |
| 3839 | 3844 |
| 3840 void Parser::ThrowPendingError() { | 3845 void Parser::ThrowPendingError() { |
| 3841 if (has_pending_error_) { | 3846 if (has_pending_error_) { |
| 3842 MessageLocation location(script_, | 3847 MessageLocation location(script_, |
| 3843 pending_error_location_.beg_pos, | 3848 pending_error_location_.beg_pos, |
| 3844 pending_error_location_.end_pos); | 3849 pending_error_location_.end_pos); |
| 3845 Factory* factory = isolate()->factory(); | 3850 Factory* factory = isolate()->factory(); |
| 3846 bool has_arg = | 3851 bool has_arg = |
| 3847 !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL; | 3852 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
| 3848 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 3853 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
| 3849 if (!pending_error_arg_.is_null()) { | 3854 if (pending_error_arg_ != NULL) { |
| 3850 elements->set(0, *(pending_error_arg_.ToHandleChecked())); | 3855 Handle<String> arg_string = pending_error_arg_->string(); |
| 3856 elements->set(0, *arg_string); |
| 3851 } else if (pending_error_char_arg_ != NULL) { | 3857 } else if (pending_error_char_arg_ != NULL) { |
| 3852 Handle<String> arg_string = | 3858 Handle<String> arg_string = |
| 3853 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 3859 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
| 3854 .ToHandleChecked(); | 3860 .ToHandleChecked(); |
| 3855 elements->set(0, *arg_string); | 3861 elements->set(0, *arg_string); |
| 3856 } | 3862 } |
| 3857 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 3863 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 3858 Handle<Object> result = pending_error_is_reference_error_ | 3864 Handle<Object> result = pending_error_is_reference_error_ |
| 3859 ? factory->NewReferenceError(pending_error_message_, array) | 3865 ? factory->NewReferenceError(pending_error_message_, array) |
| 3860 : factory->NewSyntaxError(pending_error_message_, array); | 3866 : factory->NewSyntaxError(pending_error_message_, array); |
| (...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4753 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 4759 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 4754 result->contains_anchor = parser.contains_anchor(); | 4760 result->contains_anchor = parser.contains_anchor(); |
| 4755 result->capture_count = capture_count; | 4761 result->capture_count = capture_count; |
| 4756 } | 4762 } |
| 4757 return !parser.failed(); | 4763 return !parser.failed(); |
| 4758 } | 4764 } |
| 4759 | 4765 |
| 4760 | 4766 |
| 4761 bool Parser::Parse() { | 4767 bool Parser::Parse() { |
| 4762 ASSERT(info()->function() == NULL); | 4768 ASSERT(info()->function() == NULL); |
| 4769 ASSERT(info()->ast_value_factory() == NULL); |
| 4763 FunctionLiteral* result = NULL; | 4770 FunctionLiteral* result = NULL; |
| 4771 ast_value_factory_ = new AstValueFactory(zone()); |
| 4772 if (allow_natives_syntax() || extension_ != NULL) { |
| 4773 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4774 // V8 heap because of Rumtime. Tell the string table to internalize strings |
| 4775 // and values right after they're created. |
| 4776 ast_value_factory_->Internalize(isolate()); |
| 4777 } |
| 4778 |
| 4764 if (info()->is_lazy()) { | 4779 if (info()->is_lazy()) { |
| 4765 ASSERT(!info()->is_eval()); | 4780 ASSERT(!info()->is_eval()); |
| 4766 if (info()->shared_info()->is_function()) { | 4781 if (info()->shared_info()->is_function()) { |
| 4767 result = ParseLazy(); | 4782 result = ParseLazy(); |
| 4768 } else { | 4783 } else { |
| 4769 result = ParseProgram(); | 4784 result = ParseProgram(); |
| 4770 } | 4785 } |
| 4771 } else { | 4786 } else { |
| 4772 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4787 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
| 4773 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && | 4788 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
| 4774 (*info()->cached_data())->has_error()) { | 4789 (*info()->cached_data())->has_error()) { |
| 4775 ScriptData* cached_data = *(info()->cached_data()); | 4790 ScriptData* cached_data = *(info()->cached_data()); |
| 4776 Scanner::Location loc = cached_data->MessageLocation(); | 4791 Scanner::Location loc = cached_data->MessageLocation(); |
| 4777 const char* message = cached_data->BuildMessage(); | 4792 const char* message = cached_data->BuildMessage(); |
| 4778 const char* arg = cached_data->BuildArg(); | 4793 const char* arg = cached_data->BuildArg(); |
| 4779 ParserTraits::ReportMessageAt(loc, message, arg, | 4794 ParserTraits::ReportMessageAt(loc, message, arg, |
| 4780 cached_data->IsReferenceError()); | 4795 cached_data->IsReferenceError()); |
| 4781 DeleteArray(message); | 4796 DeleteArray(message); |
| 4782 DeleteArray(arg); | 4797 DeleteArray(arg); |
| 4783 ASSERT(info()->isolate()->has_pending_exception()); | 4798 ASSERT(info()->isolate()->has_pending_exception()); |
| 4784 } else { | 4799 } else { |
| 4785 result = ParseProgram(); | 4800 result = ParseProgram(); |
| 4786 } | 4801 } |
| 4787 } | 4802 } |
| 4788 info()->SetFunction(result); | 4803 info()->SetFunction(result); |
| 4804 ast_value_factory_->Internalize(isolate()); |
| 4805 // info takes ownership of ast_value_factory_. |
| 4806 info()->SetAstValueFactory(ast_value_factory_); |
| 4807 ast_value_factory_ = NULL; |
| 4789 return (result != NULL); | 4808 return (result != NULL); |
| 4790 } | 4809 } |
| 4791 | 4810 |
| 4792 } } // namespace v8::internal | 4811 } } // namespace v8::internal |
| OLD | NEW |