| 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 ASSERT(ast_value_factory_); | 329 Scope* result = new(zone()) Scope(parent, scope_type, zone()); |
| 330 Scope* result = | |
| 331 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); | |
| 332 result->Initialize(); | 330 result->Initialize(); |
| 333 return result; | 331 return result; |
| 334 } | 332 } |
| 335 | 333 |
| 336 | 334 |
| 337 // ---------------------------------------------------------------------------- | 335 // ---------------------------------------------------------------------------- |
| 338 // Target is a support class to facilitate manipulation of the | 336 // Target is a support class to facilitate manipulation of the |
| 339 // Parser's target_stack_ (the stack of potential 'break' and | 337 // Parser's target_stack_ (the stack of potential 'break' and |
| 340 // 'continue' statement targets). Upon construction, a new target is | 338 // 'continue' statement targets). Upon construction, a new target is |
| 341 // added; it is removed upon destruction. | 339 // added; it is removed upon destruction. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 | 392 |
| 395 #define CHECK_FAILED /**/); \ | 393 #define CHECK_FAILED /**/); \ |
| 396 if (failed_) return NULL; \ | 394 if (failed_) return NULL; \ |
| 397 ((void)0 | 395 ((void)0 |
| 398 #define DUMMY ) // to make indentation work | 396 #define DUMMY ) // to make indentation work |
| 399 #undef DUMMY | 397 #undef DUMMY |
| 400 | 398 |
| 401 // ---------------------------------------------------------------------------- | 399 // ---------------------------------------------------------------------------- |
| 402 // Implementation of Parser | 400 // Implementation of Parser |
| 403 | 401 |
| 404 bool ParserTraits::IsEvalOrArguments(const AstString* identifier) const { | 402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 405 return identifier == parser_->ast_value_factory_->eval_string() || | 403 Factory* factory = parser_->isolate()->factory(); |
| 406 identifier == parser_->ast_value_factory_->arguments_string(); | 404 return identifier.is_identical_to(factory->eval_string()) |
| 405 || identifier.is_identical_to(factory->arguments_string()); |
| 407 } | 406 } |
| 408 | 407 |
| 409 | 408 |
| 410 bool ParserTraits::IsThisProperty(Expression* expression) { | 409 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 411 ASSERT(expression != NULL); | 410 ASSERT(expression != NULL); |
| 412 Property* property = expression->AsProperty(); | 411 Property* property = expression->AsProperty(); |
| 413 return property != NULL && | 412 return property != NULL && |
| 414 property->obj()->AsVariableProxy() != NULL && | 413 property->obj()->AsVariableProxy() != NULL && |
| 415 property->obj()->AsVariableProxy()->is_this(); | 414 property->obj()->AsVariableProxy()->is_this(); |
| 416 } | 415 } |
| 417 | 416 |
| 418 | 417 |
| 419 bool ParserTraits::IsIdentifier(Expression* expression) { | 418 bool ParserTraits::IsIdentifier(Expression* expression) { |
| 420 VariableProxy* operand = expression->AsVariableProxy(); | 419 VariableProxy* operand = expression->AsVariableProxy(); |
| 421 return operand != NULL && !operand->is_this(); | 420 return operand != NULL && !operand->is_this(); |
| 422 } | 421 } |
| 423 | 422 |
| 424 | 423 |
| 425 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, | 424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
| 426 Expression* expression) { | 425 Expression* expression) { |
| 427 if (expression->IsPropertyName()) { | 426 if (expression->IsPropertyName()) { |
| 428 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); | 427 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); |
| 429 } else { | 428 } else { |
| 430 fni->PushLiteralName( | 429 fni->PushLiteralName( |
| 431 parser_->ast_value_factory_->anonymous_function_string()); | 430 parser_->isolate()->factory()->anonymous_function_string()); |
| 432 } | 431 } |
| 433 } | 432 } |
| 434 | 433 |
| 435 | 434 |
| 436 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 437 Expression* right) { | 436 Expression* right) { |
| 438 ASSERT(left != NULL); | 437 ASSERT(left != NULL); |
| 439 if (left->AsProperty() != NULL && | 438 if (left->AsProperty() != NULL && |
| 440 right->AsFunctionLiteral() != NULL) { | 439 right->AsFunctionLiteral() != NULL) { |
| 441 right->AsFunctionLiteral()->set_pretenure(); | 440 right->AsFunctionLiteral()->set_pretenure(); |
| 442 } | 441 } |
| 443 } | 442 } |
| 444 | 443 |
| 445 | 444 |
| 446 void ParserTraits::CheckPossibleEvalCall(Expression* expression, | 445 void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
| 447 Scope* scope) { | 446 Scope* scope) { |
| 448 VariableProxy* callee = expression->AsVariableProxy(); | 447 VariableProxy* callee = expression->AsVariableProxy(); |
| 449 if (callee != NULL && | 448 if (callee != NULL && |
| 450 callee->raw_name() == parser_->ast_value_factory_->eval_string()) { | 449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) { |
| 451 scope->DeclarationScope()->RecordEvalCall(); | 450 scope->DeclarationScope()->RecordEvalCall(); |
| 452 } | 451 } |
| 453 } | 452 } |
| 454 | 453 |
| 455 | 454 |
| 456 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { | 455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 457 VariableProxy* proxy = expression != NULL | 456 VariableProxy* proxy = expression != NULL |
| 458 ? expression->AsVariableProxy() | 457 ? expression->AsVariableProxy() |
| 459 : NULL; | 458 : NULL; |
| 460 if (proxy != NULL) proxy->MarkAsLValue(); | 459 if (proxy != NULL) proxy->MarkAsLValue(); |
| 461 return expression; | 460 return expression; |
| 462 } | 461 } |
| 463 | 462 |
| 464 | 463 |
| 465 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( | 464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
| 466 Expression** x, Expression* y, Token::Value op, int pos, | 465 Expression** x, Expression* y, Token::Value op, int pos, |
| 467 AstNodeFactory<AstConstructionVisitor>* factory) { | 466 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 468 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && | 467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && |
| 469 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { | 468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
| 470 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); | 469 double x_val = (*x)->AsLiteral()->value()->Number(); |
| 471 double y_val = y->AsLiteral()->raw_value()->AsNumber(); | 470 double y_val = y->AsLiteral()->value()->Number(); |
| 472 switch (op) { | 471 switch (op) { |
| 473 case Token::ADD: | 472 case Token::ADD: |
| 474 *x = factory->NewNumberLiteral(x_val + y_val, pos); | 473 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| 475 return true; | 474 return true; |
| 476 case Token::SUB: | 475 case Token::SUB: |
| 477 *x = factory->NewNumberLiteral(x_val - y_val, pos); | 476 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
| 478 return true; | 477 return true; |
| 479 case Token::MUL: | 478 case Token::MUL: |
| 480 *x = factory->NewNumberLiteral(x_val * y_val, pos); | 479 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
| 481 return true; | 480 return true; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 519 } |
| 521 return false; | 520 return false; |
| 522 } | 521 } |
| 523 | 522 |
| 524 | 523 |
| 525 Expression* ParserTraits::BuildUnaryExpression( | 524 Expression* ParserTraits::BuildUnaryExpression( |
| 526 Expression* expression, Token::Value op, int pos, | 525 Expression* expression, Token::Value op, int pos, |
| 527 AstNodeFactory<AstConstructionVisitor>* factory) { | 526 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 528 ASSERT(expression != NULL); | 527 ASSERT(expression != NULL); |
| 529 if (expression->IsLiteral()) { | 528 if (expression->IsLiteral()) { |
| 530 const AstValue* literal = expression->AsLiteral()->raw_value(); | 529 Handle<Object> literal = expression->AsLiteral()->value(); |
| 531 if (op == Token::NOT) { | 530 if (op == Token::NOT) { |
| 532 // Convert the literal to a boolean condition and negate it. | 531 // Convert the literal to a boolean condition and negate it. |
| 533 bool condition = literal->BooleanValue(); | 532 bool condition = literal->BooleanValue(); |
| 534 return factory->NewBooleanLiteral(!condition, pos); | 533 Handle<Object> result = |
| 534 parser_->isolate()->factory()->ToBoolean(!condition); |
| 535 return factory->NewLiteral(result, pos); |
| 535 } else if (literal->IsNumber()) { | 536 } else if (literal->IsNumber()) { |
| 536 // Compute some expressions involving only number literals. | 537 // Compute some expressions involving only number literals. |
| 537 double value = literal->AsNumber(); | 538 double value = literal->Number(); |
| 538 switch (op) { | 539 switch (op) { |
| 539 case Token::ADD: | 540 case Token::ADD: |
| 540 return expression; | 541 return expression; |
| 541 case Token::SUB: | 542 case Token::SUB: |
| 542 return factory->NewNumberLiteral(-value, pos); | 543 return factory->NewNumberLiteral(-value, pos); |
| 543 case Token::BIT_NOT: | 544 case Token::BIT_NOT: |
| 544 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); | 545 return factory->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 545 default: | 546 default: |
| 546 break; | 547 break; |
| 547 } | 548 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 561 if (op == Token::BIT_NOT) { | 562 if (op == Token::BIT_NOT) { |
| 562 return factory->NewBinaryOperation( | 563 return factory->NewBinaryOperation( |
| 563 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
| 564 } | 565 } |
| 565 return factory->NewUnaryOperation(op, expression, pos); | 566 return factory->NewUnaryOperation(op, expression, pos); |
| 566 } | 567 } |
| 567 | 568 |
| 568 | 569 |
| 569 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { | 570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
| 570 return NewThrowError( | 571 return NewThrowError( |
| 571 parser_->ast_value_factory_->make_reference_error_string(), message, NULL, | 572 parser_->isolate()->factory()->MakeReferenceError_string(), |
| 572 pos); | 573 message, HandleVector<Object>(NULL, 0), pos); |
| 573 } | 574 } |
| 574 | 575 |
| 575 | 576 |
| 576 Expression* ParserTraits::NewThrowSyntaxError( | 577 Expression* ParserTraits::NewThrowSyntaxError( |
| 577 const char* message, const AstString* arg, int pos) { | 578 const char* message, Handle<Object> arg, int pos) { |
| 578 return NewThrowError(parser_->ast_value_factory_->make_syntax_error_string(), | 579 int argc = arg.is_null() ? 0 : 1; |
| 579 message, arg, pos); | 580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
| 581 return NewThrowError( |
| 582 parser_->isolate()->factory()->MakeSyntaxError_string(), |
| 583 message, arguments, pos); |
| 580 } | 584 } |
| 581 | 585 |
| 582 | 586 |
| 583 Expression* ParserTraits::NewThrowTypeError( | 587 Expression* ParserTraits::NewThrowTypeError( |
| 584 const char* message, const AstString* arg, int pos) { | 588 const char* message, Handle<Object> arg, int pos) { |
| 585 return NewThrowError(parser_->ast_value_factory_->make_type_error_string(), | 589 int argc = arg.is_null() ? 0 : 1; |
| 586 message, arg, pos); | 590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
| 591 return NewThrowError( |
| 592 parser_->isolate()->factory()->MakeTypeError_string(), |
| 593 message, arguments, pos); |
| 587 } | 594 } |
| 588 | 595 |
| 589 | 596 |
| 590 Expression* ParserTraits::NewThrowError( | 597 Expression* ParserTraits::NewThrowError( |
| 591 const AstString* constructor, const char* message, | 598 Handle<String> constructor, const char* message, |
| 592 const AstString* arg, int pos) { | 599 Vector<Handle<Object> > arguments, int pos) { |
| 593 Zone* zone = parser_->zone(); | 600 Zone* zone = parser_->zone(); |
| 594 int argc = arg != NULL ? 1 : 0; | 601 Factory* factory = parser_->isolate()->factory(); |
| 595 const AstString* type = | 602 int argc = arguments.length(); |
| 596 parser_->ast_value_factory_->GetOneByteString(Vector<const uint8_t>( | 603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); |
| 597 reinterpret_cast<const uint8_t*>(message), StrLength(message))); | 604 for (int i = 0; i < argc; i++) { |
| 598 ZoneList<const AstString*>* array = | 605 Handle<Object> element = arguments[i]; |
| 599 new (zone) ZoneList<const AstString*>(argc, zone); | 606 if (!element.is_null()) { |
| 600 if (arg != NULL) { | 607 elements->set(i, *element); |
| 601 array->Add(arg, zone); | 608 } |
| 602 } | 609 } |
| 603 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); | 610 Handle<JSArray> array = |
| 604 args->Add(parser_->factory()->NewStringLiteral(type, pos), zone); | 611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); |
| 605 args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone); | 612 |
| 613 ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone); |
| 614 Handle<String> type = factory->InternalizeUtf8String(message); |
| 615 args->Add(parser_->factory()->NewLiteral(type, pos), zone); |
| 616 args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
| 606 CallRuntime* call_constructor = | 617 CallRuntime* call_constructor = |
| 607 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); | 618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
| 608 return parser_->factory()->NewThrow(call_constructor, pos); | 619 return parser_->factory()->NewThrow(call_constructor, pos); |
| 609 } | 620 } |
| 610 | 621 |
| 611 | 622 |
| 612 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 623 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 613 const char* message, | 624 const char* message, |
| 614 const char* arg, | 625 const char* arg, |
| 615 bool is_reference_error) { | 626 bool is_reference_error) { |
| 616 if (parser_->stack_overflow()) { | 627 if (parser_->stack_overflow()) { |
| 617 // Suppress the error message (syntax error or such) in the presence of a | 628 // Suppress the error message (syntax error or such) in the presence of a |
| 618 // stack overflow. The isolate allows only one pending exception at at time | 629 // stack overflow. The isolate allows only one pending exception at at time |
| 619 // and we want to report the stack overflow later. | 630 // and we want to report the stack overflow later. |
| 620 return; | 631 return; |
| 621 } | 632 } |
| 622 parser_->has_pending_error_ = true; | 633 parser_->has_pending_error_ = true; |
| 623 parser_->pending_error_location_ = source_location; | 634 parser_->pending_error_location_ = source_location; |
| 624 parser_->pending_error_message_ = message; | 635 parser_->pending_error_message_ = message; |
| 625 parser_->pending_error_char_arg_ = arg; | 636 parser_->pending_error_char_arg_ = arg; |
| 626 parser_->pending_error_arg_ = NULL; | 637 parser_->pending_error_arg_ = Handle<String>(); |
| 627 parser_->pending_error_is_reference_error_ = is_reference_error; | 638 parser_->pending_error_is_reference_error_ = is_reference_error; |
| 628 } | 639 } |
| 629 | 640 |
| 630 | 641 |
| 631 void ParserTraits::ReportMessage(const char* message, | 642 void ParserTraits::ReportMessage(const char* message, |
| 632 const char* arg, | 643 MaybeHandle<String> arg, |
| 633 bool is_reference_error) { | 644 bool is_reference_error) { |
| 634 Scanner::Location source_location = parser_->scanner()->location(); | 645 Scanner::Location source_location = parser_->scanner()->location(); |
| 635 ReportMessageAt(source_location, message, arg, is_reference_error); | 646 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); | |
| 644 } | 647 } |
| 645 | 648 |
| 646 | 649 |
| 647 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 650 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 648 const char* message, | 651 const char* message, |
| 649 const AstString* arg, | 652 MaybeHandle<String> arg, |
| 650 bool is_reference_error) { | 653 bool is_reference_error) { |
| 651 if (parser_->stack_overflow()) { | 654 if (parser_->stack_overflow()) { |
| 652 // Suppress the error message (syntax error or such) in the presence of a | 655 // Suppress the error message (syntax error or such) in the presence of a |
| 653 // stack overflow. The isolate allows only one pending exception at at time | 656 // stack overflow. The isolate allows only one pending exception at at time |
| 654 // and we want to report the stack overflow later. | 657 // and we want to report the stack overflow later. |
| 655 return; | 658 return; |
| 656 } | 659 } |
| 657 parser_->has_pending_error_ = true; | 660 parser_->has_pending_error_ = true; |
| 658 parser_->pending_error_location_ = source_location; | 661 parser_->pending_error_location_ = source_location; |
| 659 parser_->pending_error_message_ = message; | 662 parser_->pending_error_message_ = message; |
| 660 parser_->pending_error_char_arg_ = NULL; | 663 parser_->pending_error_char_arg_ = NULL; |
| 661 parser_->pending_error_arg_ = arg; | 664 parser_->pending_error_arg_ = arg; |
| 662 parser_->pending_error_is_reference_error_ = is_reference_error; | 665 parser_->pending_error_is_reference_error_ = is_reference_error; |
| 663 } | 666 } |
| 664 | 667 |
| 665 | 668 |
| 666 const AstString* ParserTraits::GetSymbol(Scanner* scanner) { | 669 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
| 667 const AstString* result = | 670 Handle<String> result = |
| 668 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); | 671 parser_->scanner()->AllocateInternalizedString(parser_->isolate()); |
| 669 ASSERT(result != NULL); | 672 ASSERT(!result.is_null()); |
| 670 return result; | 673 return result; |
| 671 } | 674 } |
| 672 | 675 |
| 673 | 676 |
| 674 const AstString* ParserTraits::GetNextSymbol(Scanner* scanner) { | 677 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
| 675 return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); | 678 PretenureFlag tenured) { |
| 679 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
| 676 } | 680 } |
| 677 | 681 |
| 678 | 682 |
| 679 Expression* ParserTraits::ThisExpression( | 683 Expression* ParserTraits::ThisExpression( |
| 680 Scope* scope, | 684 Scope* scope, |
| 681 AstNodeFactory<AstConstructionVisitor>* factory) { | 685 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 682 return factory->NewVariableProxy(scope->receiver()); | 686 return factory->NewVariableProxy(scope->receiver()); |
| 683 } | 687 } |
| 684 | 688 |
| 685 | 689 |
| 686 Literal* ParserTraits::ExpressionFromLiteral( | 690 Literal* ParserTraits::ExpressionFromLiteral( |
| 687 Token::Value token, int pos, | 691 Token::Value token, int pos, |
| 688 Scanner* scanner, | 692 Scanner* scanner, |
| 689 AstNodeFactory<AstConstructionVisitor>* factory) { | 693 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 694 Factory* isolate_factory = parser_->isolate()->factory(); |
| 690 switch (token) { | 695 switch (token) { |
| 691 case Token::NULL_LITERAL: | 696 case Token::NULL_LITERAL: |
| 692 return factory->NewNullLiteral(pos); | 697 return factory->NewLiteral(isolate_factory->null_value(), pos); |
| 693 case Token::TRUE_LITERAL: | 698 case Token::TRUE_LITERAL: |
| 694 return factory->NewBooleanLiteral(true, pos); | 699 return factory->NewLiteral(isolate_factory->true_value(), pos); |
| 695 case Token::FALSE_LITERAL: | 700 case Token::FALSE_LITERAL: |
| 696 return factory->NewBooleanLiteral(false, pos); | 701 return factory->NewLiteral(isolate_factory->false_value(), pos); |
| 697 case Token::NUMBER: { | 702 case Token::NUMBER: { |
| 698 double value = scanner->DoubleValue(); | 703 double value = scanner->DoubleValue(); |
| 699 return factory->NewNumberLiteral(value, pos); | 704 return factory->NewNumberLiteral(value, pos); |
| 700 } | 705 } |
| 701 default: | 706 default: |
| 702 ASSERT(false); | 707 ASSERT(false); |
| 703 } | 708 } |
| 704 return NULL; | 709 return NULL; |
| 705 } | 710 } |
| 706 | 711 |
| 707 | 712 |
| 708 Expression* ParserTraits::ExpressionFromIdentifier( | 713 Expression* ParserTraits::ExpressionFromIdentifier( |
| 709 const AstString* name, int pos, Scope* scope, | 714 Handle<String> name, int pos, Scope* scope, |
| 710 AstNodeFactory<AstConstructionVisitor>* factory) { | 715 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 711 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 716 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 712 // The name may refer to a module instance object, so its type is unknown. | 717 // The name may refer to a module instance object, so its type is unknown. |
| 713 #ifdef DEBUG | 718 #ifdef DEBUG |
| 714 if (FLAG_print_interface_details) | 719 if (FLAG_print_interface_details) |
| 715 PrintF("# Variable %.*s ", name->length(), name->raw_data()); | 720 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 716 #endif | 721 #endif |
| 717 Interface* interface = Interface::NewUnknown(parser_->zone()); | 722 Interface* interface = Interface::NewUnknown(parser_->zone()); |
| 718 return scope->NewUnresolved(factory, name, interface, pos); | 723 return scope->NewUnresolved(factory, name, interface, pos); |
| 719 } | 724 } |
| 720 | 725 |
| 721 | 726 |
| 722 Expression* ParserTraits::ExpressionFromString( | 727 Expression* ParserTraits::ExpressionFromString( |
| 723 int pos, Scanner* scanner, | 728 int pos, Scanner* scanner, |
| 724 AstNodeFactory<AstConstructionVisitor>* factory) { | 729 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 725 const AstString* symbol = GetSymbol(scanner); | 730 Handle<String> symbol = GetSymbol(scanner); |
| 726 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 731 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 727 return factory->NewStringLiteral(symbol, pos); | 732 return factory->NewLiteral(symbol, pos); |
| 728 } | 733 } |
| 729 | 734 |
| 730 | 735 |
| 731 Literal* ParserTraits::GetLiteralTheHole( | 736 Literal* ParserTraits::GetLiteralTheHole( |
| 732 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 737 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 733 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition); | 738 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| 739 RelocInfo::kNoPosition); |
| 734 } | 740 } |
| 735 | 741 |
| 736 | 742 |
| 737 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 743 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 738 return parser_->ParseV8Intrinsic(ok); | 744 return parser_->ParseV8Intrinsic(ok); |
| 739 } | 745 } |
| 740 | 746 |
| 741 | 747 |
| 742 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 748 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| 743 const AstString* name, | 749 Handle<String> name, |
| 744 Scanner::Location function_name_location, | 750 Scanner::Location function_name_location, |
| 745 bool name_is_strict_reserved, | 751 bool name_is_strict_reserved, |
| 746 bool is_generator, | 752 bool is_generator, |
| 747 int function_token_position, | 753 int function_token_position, |
| 748 FunctionLiteral::FunctionType type, | 754 FunctionLiteral::FunctionType type, |
| 749 FunctionLiteral::ArityRestriction arity_restriction, | 755 FunctionLiteral::ArityRestriction arity_restriction, |
| 750 bool* ok) { | 756 bool* ok) { |
| 751 return parser_->ParseFunctionLiteral(name, function_name_location, | 757 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 752 name_is_strict_reserved, is_generator, | 758 name_is_strict_reserved, is_generator, |
| 753 function_token_position, type, | 759 function_token_position, type, |
| 754 arity_restriction, ok); | 760 arity_restriction, ok); |
| 755 } | 761 } |
| 756 | 762 |
| 757 | 763 |
| 758 Parser::Parser(CompilationInfo* info) | 764 Parser::Parser(CompilationInfo* info) |
| 759 : ParserBase<ParserTraits>(&scanner_, | 765 : ParserBase<ParserTraits>(&scanner_, |
| 760 info->isolate()->stack_guard()->real_climit(), | 766 info->isolate()->stack_guard()->real_climit(), |
| 761 info->extension(), | 767 info->extension(), |
| 762 NULL, | 768 NULL, |
| 763 info->zone(), | 769 info->zone(), |
| 764 this), | 770 this), |
| 765 isolate_(info->isolate()), | 771 isolate_(info->isolate()), |
| 766 script_(info->script()), | 772 script_(info->script()), |
| 767 scanner_(isolate_->unicode_cache()), | 773 scanner_(isolate_->unicode_cache()), |
| 768 reusable_preparser_(NULL), | 774 reusable_preparser_(NULL), |
| 769 original_scope_(NULL), | 775 original_scope_(NULL), |
| 770 target_stack_(NULL), | 776 target_stack_(NULL), |
| 771 cached_data_(NULL), | 777 cached_data_(NULL), |
| 772 cached_data_mode_(NO_CACHED_DATA), | 778 cached_data_mode_(NO_CACHED_DATA), |
| 773 ast_value_factory_(NULL), | |
| 774 info_(info), | 779 info_(info), |
| 775 has_pending_error_(false), | 780 has_pending_error_(false), |
| 776 pending_error_message_(NULL), | 781 pending_error_message_(NULL), |
| 777 pending_error_arg_(NULL), | |
| 778 pending_error_char_arg_(NULL) { | 782 pending_error_char_arg_(NULL) { |
| 779 ASSERT(!script_.is_null()); | 783 ASSERT(!script_.is_null()); |
| 780 isolate_->set_ast_node_id(0); | 784 isolate_->set_ast_node_id(0); |
| 781 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 785 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 782 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 786 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 783 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 787 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 784 set_allow_lazy(false); // Must be explicitly enabled. | 788 set_allow_lazy(false); // Must be explicitly enabled. |
| 785 set_allow_generators(FLAG_harmony_generators); | 789 set_allow_generators(FLAG_harmony_generators); |
| 786 set_allow_for_of(FLAG_harmony_iteration); | 790 set_allow_for_of(FLAG_harmony_iteration); |
| 787 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 791 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 788 } | 792 } |
| 789 | 793 |
| 790 | 794 |
| 791 FunctionLiteral* Parser::ParseProgram() { | 795 FunctionLiteral* Parser::ParseProgram() { |
| 792 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 796 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 793 // see comment for HistogramTimerScope class. | 797 // see comment for HistogramTimerScope class. |
| 794 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 798 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 795 Handle<String> source(String::cast(script_->source())); | 799 Handle<String> source(String::cast(script_->source())); |
| 796 isolate()->counters()->total_parse_size()->Increment(source->length()); | 800 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 797 ElapsedTimer timer; | 801 ElapsedTimer timer; |
| 798 if (FLAG_trace_parse) { | 802 if (FLAG_trace_parse) { |
| 799 timer.Start(); | 803 timer.Start(); |
| 800 } | 804 } |
| 801 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 805 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 802 | 806 |
| 803 // Initialize parser state. | 807 // Initialize parser state. |
| 804 CompleteParserRecorder recorder; | 808 CompleteParserRecorder recorder; |
| 805 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 809 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 806 log_ = &recorder; | 810 log_ = &recorder; |
| 807 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 811 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 808 (*cached_data_)->Initialize(); | 812 (*cached_data_)->Initialize(); |
| 809 } | 813 } |
| 810 | 814 |
| 811 source = String::Flatten(source); | 815 source = String::Flatten(source); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 } | 850 } |
| 847 return result; | 851 return result; |
| 848 } | 852 } |
| 849 | 853 |
| 850 | 854 |
| 851 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 855 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 852 Handle<String> source) { | 856 Handle<String> source) { |
| 853 ASSERT(scope_ == NULL); | 857 ASSERT(scope_ == NULL); |
| 854 ASSERT(target_stack_ == NULL); | 858 ASSERT(target_stack_ == NULL); |
| 855 | 859 |
| 860 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 861 |
| 856 FunctionLiteral* result = NULL; | 862 FunctionLiteral* result = NULL; |
| 857 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 863 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 858 info->SetGlobalScope(scope); | 864 info->SetGlobalScope(scope); |
| 859 if (!info->context().is_null()) { | 865 if (!info->context().is_null()) { |
| 860 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 866 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 861 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | |
| 862 // means the Parser cannot operate independent of the V8 heap. Tell the | |
| 863 // string table to internalize strings and values right after they're | |
| 864 // created. | |
| 865 ast_value_factory_->Internalize(isolate()); | |
| 866 } | 867 } |
| 867 original_scope_ = scope; | 868 original_scope_ = scope; |
| 868 if (info->is_eval()) { | 869 if (info->is_eval()) { |
| 869 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { | 870 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
| 870 scope = NewScope(scope, EVAL_SCOPE); | 871 scope = NewScope(scope, EVAL_SCOPE); |
| 871 } | 872 } |
| 872 } else if (info->is_global()) { | 873 } else if (info->is_global()) { |
| 873 scope = NewScope(scope, GLOBAL_SCOPE); | 874 scope = NewScope(scope, GLOBAL_SCOPE); |
| 874 } | 875 } |
| 875 scope->set_start_position(0); | 876 scope->set_start_position(0); |
| 876 scope->set_end_position(source->length()); | 877 scope->set_end_position(source->length()); |
| 877 | 878 |
| 878 // Compute the parsing mode. | 879 // Compute the parsing mode. |
| 879 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 880 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 880 if (allow_natives_syntax() || | 881 if (allow_natives_syntax() || |
| 881 extension_ != NULL || | 882 extension_ != NULL || |
| 882 scope->is_eval_scope()) { | 883 scope->is_eval_scope()) { |
| 883 mode = PARSE_EAGERLY; | 884 mode = PARSE_EAGERLY; |
| 884 } | 885 } |
| 885 ParsingModeScope parsing_mode(this, mode); | 886 ParsingModeScope parsing_mode(this, mode); |
| 886 | 887 |
| 887 // Enters 'scope'. | 888 // Enters 'scope'. |
| 888 FunctionState function_state(&function_state_, &scope_, scope, zone(), | 889 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 889 ast_value_factory_); | |
| 890 | 890 |
| 891 scope_->SetStrictMode(info->strict_mode()); | 891 scope_->SetStrictMode(info->strict_mode()); |
| 892 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 892 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 893 bool ok = true; | 893 bool ok = true; |
| 894 int beg_pos = scanner()->location().beg_pos; | 894 int beg_pos = scanner()->location().beg_pos; |
| 895 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 895 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 896 if (ok && strict_mode() == STRICT) { | 896 if (ok && strict_mode() == STRICT) { |
| 897 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 897 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 898 } | 898 } |
| 899 | 899 |
| 900 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 900 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 901 CheckConflictingVarDeclarations(scope_, &ok); | 901 CheckConflictingVarDeclarations(scope_, &ok); |
| 902 } | 902 } |
| 903 | 903 |
| 904 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 904 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 905 if (body->length() != 1 || | 905 if (body->length() != 1 || |
| 906 !body->at(0)->IsExpressionStatement() || | 906 !body->at(0)->IsExpressionStatement() || |
| 907 !body->at(0)->AsExpressionStatement()-> | 907 !body->at(0)->AsExpressionStatement()-> |
| 908 expression()->IsFunctionLiteral()) { | 908 expression()->IsFunctionLiteral()) { |
| 909 ReportMessage("single_function_literal"); | 909 ReportMessage("single_function_literal"); |
| 910 ok = false; | 910 ok = false; |
| 911 } | 911 } |
| 912 } | 912 } |
| 913 | 913 |
| 914 ast_value_factory_->Internalize(isolate()); | |
| 915 if (ok) { | 914 if (ok) { |
| 916 result = factory()->NewFunctionLiteral( | 915 result = factory()->NewFunctionLiteral( |
| 917 ast_value_factory_->empty_string(), | 916 no_name, |
| 918 ast_value_factory_, | |
| 919 scope_, | 917 scope_, |
| 920 body, | 918 body, |
| 921 function_state.materialized_literal_count(), | 919 function_state.materialized_literal_count(), |
| 922 function_state.expected_property_count(), | 920 function_state.expected_property_count(), |
| 923 function_state.handler_count(), | 921 function_state.handler_count(), |
| 924 0, | 922 0, |
| 925 FunctionLiteral::kNoDuplicateParameters, | 923 FunctionLiteral::kNoDuplicateParameters, |
| 926 FunctionLiteral::ANONYMOUS_EXPRESSION, | 924 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 927 FunctionLiteral::kGlobalOrEval, | 925 FunctionLiteral::kGlobalOrEval, |
| 928 FunctionLiteral::kNotParenthesized, | 926 FunctionLiteral::kNotParenthesized, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 } | 978 } |
| 981 | 979 |
| 982 | 980 |
| 983 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 981 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 984 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 982 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 985 scanner_.Initialize(source); | 983 scanner_.Initialize(source); |
| 986 ASSERT(scope_ == NULL); | 984 ASSERT(scope_ == NULL); |
| 987 ASSERT(target_stack_ == NULL); | 985 ASSERT(target_stack_ == NULL); |
| 988 | 986 |
| 989 Handle<String> name(String::cast(shared_info->name())); | 987 Handle<String> name(String::cast(shared_info->name())); |
| 990 ASSERT(ast_value_factory_); | 988 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 991 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 989 fni_->PushEnclosingName(name); |
| 992 const AstString* raw_name = ast_value_factory_->GetString(name); | |
| 993 fni_->PushEnclosingName(raw_name); | |
| 994 | 990 |
| 995 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 991 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 996 | 992 |
| 997 // Place holder for the result. | 993 // Place holder for the result. |
| 998 FunctionLiteral* result = NULL; | 994 FunctionLiteral* result = NULL; |
| 999 | 995 |
| 1000 { | 996 { |
| 1001 // Parse the function literal. | 997 // Parse the function literal. |
| 1002 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 998 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 1003 info()->SetGlobalScope(scope); | 999 info()->SetGlobalScope(scope); |
| 1004 if (!info()->closure().is_null()) { | 1000 if (!info()->closure().is_null()) { |
| 1005 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 1001 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 1006 zone()); | 1002 zone()); |
| 1007 } | 1003 } |
| 1008 original_scope_ = scope; | 1004 original_scope_ = scope; |
| 1009 FunctionState function_state(&function_state_, &scope_, scope, zone(), | 1005 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 1010 ast_value_factory_); | |
| 1011 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); | 1006 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| 1012 ASSERT(info()->strict_mode() == shared_info->strict_mode()); | 1007 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
| 1013 scope->SetStrictMode(shared_info->strict_mode()); | 1008 scope->SetStrictMode(shared_info->strict_mode()); |
| 1014 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1009 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 1015 ? (shared_info->is_anonymous() | 1010 ? (shared_info->is_anonymous() |
| 1016 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1011 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 1017 : FunctionLiteral::NAMED_EXPRESSION) | 1012 : FunctionLiteral::NAMED_EXPRESSION) |
| 1018 : FunctionLiteral::DECLARATION; | 1013 : FunctionLiteral::DECLARATION; |
| 1019 bool ok = true; | 1014 bool ok = true; |
| 1020 result = ParseFunctionLiteral(raw_name, | 1015 result = ParseFunctionLiteral(name, |
| 1021 Scanner::Location::invalid(), | 1016 Scanner::Location::invalid(), |
| 1022 false, // Strict mode name already checked. | 1017 false, // Strict mode name already checked. |
| 1023 shared_info->is_generator(), | 1018 shared_info->is_generator(), |
| 1024 RelocInfo::kNoPosition, | 1019 RelocInfo::kNoPosition, |
| 1025 function_type, | 1020 function_type, |
| 1026 FunctionLiteral::NORMAL_ARITY, | 1021 FunctionLiteral::NORMAL_ARITY, |
| 1027 &ok); | 1022 &ok); |
| 1028 // Make sure the results agree. | 1023 // Make sure the results agree. |
| 1029 ASSERT(ok == (result != NULL)); | 1024 ASSERT(ok == (result != NULL)); |
| 1030 } | 1025 } |
| 1031 | 1026 |
| 1032 // Make sure the target stack is empty. | 1027 // Make sure the target stack is empty. |
| 1033 ASSERT(target_stack_ == NULL); | 1028 ASSERT(target_stack_ == NULL); |
| 1034 | 1029 |
| 1035 ast_value_factory_->Internalize(isolate()); | |
| 1036 if (result == NULL) { | 1030 if (result == NULL) { |
| 1037 if (stack_overflow()) { | 1031 if (stack_overflow()) { |
| 1038 isolate()->StackOverflow(); | 1032 isolate()->StackOverflow(); |
| 1039 } else { | 1033 } else { |
| 1040 ThrowPendingError(); | 1034 ThrowPendingError(); |
| 1041 } | 1035 } |
| 1042 } else { | 1036 } else { |
| 1043 Handle<String> inferred_name(shared_info->inferred_name()); | 1037 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1044 result->set_inferred_name(inferred_name); | 1038 result->set_inferred_name(inferred_name); |
| 1045 } | 1039 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 continue; | 1075 continue; |
| 1082 } | 1076 } |
| 1083 | 1077 |
| 1084 if (directive_prologue) { | 1078 if (directive_prologue) { |
| 1085 // A shot at a directive. | 1079 // A shot at a directive. |
| 1086 ExpressionStatement* e_stat; | 1080 ExpressionStatement* e_stat; |
| 1087 Literal* literal; | 1081 Literal* literal; |
| 1088 // Still processing directive prologue? | 1082 // Still processing directive prologue? |
| 1089 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1083 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1090 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1084 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1091 literal->raw_value()->IsString()) { | 1085 literal->value()->IsString()) { |
| 1086 Handle<String> directive = Handle<String>::cast(literal->value()); |
| 1087 |
| 1092 // Check "use strict" directive (ES5 14.1). | 1088 // Check "use strict" directive (ES5 14.1). |
| 1093 if (strict_mode() == SLOPPY && | 1089 if (strict_mode() == SLOPPY && |
| 1094 literal->raw_value()->AsString() == | 1090 String::Equals(isolate()->factory()->use_strict_string(), |
| 1095 ast_value_factory_->use_strict_string() && | 1091 directive) && |
| 1096 token_loc.end_pos - token_loc.beg_pos == 12) { | 1092 token_loc.end_pos - token_loc.beg_pos == |
| 1093 isolate()->heap()->use_strict_string()->length() + 2) { |
| 1097 // TODO(mstarzinger): Global strict eval calls, need their own scope | 1094 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 1098 // as specified in ES5 10.4.2(3). The correct fix would be to always | 1095 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 1099 // add this scope in DoParseProgram(), but that requires adaptations | 1096 // add this scope in DoParseProgram(), but that requires adaptations |
| 1100 // all over the code base, so we go with a quick-fix for now. | 1097 // all over the code base, so we go with a quick-fix for now. |
| 1101 // In the same manner, we have to patch the parsing mode. | 1098 // In the same manner, we have to patch the parsing mode. |
| 1102 if (is_eval && !scope_->is_eval_scope()) { | 1099 if (is_eval && !scope_->is_eval_scope()) { |
| 1103 ASSERT(scope_->is_global_scope()); | 1100 ASSERT(scope_->is_global_scope()); |
| 1104 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 1101 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 1105 scope->set_start_position(scope_->start_position()); | 1102 scope->set_start_position(scope_->start_position()); |
| 1106 scope->set_end_position(scope_->end_position()); | 1103 scope->set_end_position(scope_->end_position()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1117 } | 1114 } |
| 1118 } | 1115 } |
| 1119 | 1116 |
| 1120 processor->Add(stat, zone()); | 1117 processor->Add(stat, zone()); |
| 1121 } | 1118 } |
| 1122 | 1119 |
| 1123 return 0; | 1120 return 0; |
| 1124 } | 1121 } |
| 1125 | 1122 |
| 1126 | 1123 |
| 1127 Statement* Parser::ParseModuleElement(ZoneList<const AstString*>* labels, | 1124 Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
| 1128 bool* ok) { | 1125 bool* ok) { |
| 1129 // (Ecma 262 5th Edition, clause 14): | 1126 // (Ecma 262 5th Edition, clause 14): |
| 1130 // SourceElement: | 1127 // SourceElement: |
| 1131 // Statement | 1128 // Statement |
| 1132 // FunctionDeclaration | 1129 // FunctionDeclaration |
| 1133 // | 1130 // |
| 1134 // In harmony mode we allow additionally the following productions | 1131 // In harmony mode we allow additionally the following productions |
| 1135 // ModuleElement: | 1132 // ModuleElement: |
| 1136 // LetDeclaration | 1133 // LetDeclaration |
| 1137 // ConstDeclaration | 1134 // ConstDeclaration |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1151 case Token::EXPORT: | 1148 case Token::EXPORT: |
| 1152 return ParseExportDeclaration(ok); | 1149 return ParseExportDeclaration(ok); |
| 1153 default: { | 1150 default: { |
| 1154 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1151 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 1155 // Handle 'module' as a context-sensitive keyword. | 1152 // Handle 'module' as a context-sensitive keyword. |
| 1156 if (FLAG_harmony_modules && | 1153 if (FLAG_harmony_modules && |
| 1157 peek() == Token::IDENTIFIER && | 1154 peek() == Token::IDENTIFIER && |
| 1158 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1155 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 1159 stmt != NULL) { | 1156 stmt != NULL) { |
| 1160 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1157 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
| 1161 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && | 1158 if (estmt != NULL && |
| 1162 estmt->expression()->AsVariableProxy()->raw_name() == | 1159 estmt->expression()->AsVariableProxy() != NULL && |
| 1163 ast_value_factory_->module_string() && | 1160 String::Equals(isolate()->factory()->module_string(), |
| 1161 estmt->expression()->AsVariableProxy()->name()) && |
| 1164 !scanner()->literal_contains_escapes()) { | 1162 !scanner()->literal_contains_escapes()) { |
| 1165 return ParseModuleDeclaration(NULL, ok); | 1163 return ParseModuleDeclaration(NULL, ok); |
| 1166 } | 1164 } |
| 1167 } | 1165 } |
| 1168 return stmt; | 1166 return stmt; |
| 1169 } | 1167 } |
| 1170 } | 1168 } |
| 1171 } | 1169 } |
| 1172 | 1170 |
| 1173 | 1171 |
| 1174 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstString*>* names, | 1172 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 1175 bool* ok) { | |
| 1176 // ModuleDeclaration: | 1173 // ModuleDeclaration: |
| 1177 // 'module' Identifier Module | 1174 // 'module' Identifier Module |
| 1178 | 1175 |
| 1179 int pos = peek_position(); | 1176 int pos = peek_position(); |
| 1180 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1177 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1181 | 1178 |
| 1182 #ifdef DEBUG | 1179 #ifdef DEBUG |
| 1183 if (FLAG_print_interface_details) | 1180 if (FLAG_print_interface_details) |
| 1184 PrintF("# Module %.*s ", name->length(), name->raw_data()); | 1181 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 1185 #endif | 1182 #endif |
| 1186 | 1183 |
| 1187 Module* module = ParseModule(CHECK_OK); | 1184 Module* module = ParseModule(CHECK_OK); |
| 1188 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1185 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 1189 Declaration* declaration = | 1186 Declaration* declaration = |
| 1190 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 1187 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
| 1191 Declare(declaration, true, CHECK_OK); | 1188 Declare(declaration, true, CHECK_OK); |
| 1192 | 1189 |
| 1193 #ifdef DEBUG | 1190 #ifdef DEBUG |
| 1194 if (FLAG_print_interface_details) | 1191 if (FLAG_print_interface_details) |
| 1195 PrintF("# Module %.*s ", name->length(), name->raw_data()); | 1192 PrintF("# Module %s.\n", name->ToAsciiArray()); |
| 1193 |
| 1196 if (FLAG_print_interfaces) { | 1194 if (FLAG_print_interfaces) { |
| 1197 PrintF("module %.*s: ", name->length(), name->raw_data()); | 1195 PrintF("module %s : ", name->ToAsciiArray()); |
| 1198 module->interface()->Print(); | 1196 module->interface()->Print(); |
| 1199 } | 1197 } |
| 1200 #endif | 1198 #endif |
| 1201 | 1199 |
| 1202 if (names) names->Add(name, zone()); | 1200 if (names) names->Add(name, zone()); |
| 1203 if (module->body() == NULL) | 1201 if (module->body() == NULL) |
| 1204 return factory()->NewEmptyStatement(pos); | 1202 return factory()->NewEmptyStatement(pos); |
| 1205 else | 1203 else |
| 1206 return factory()->NewModuleStatement(proxy, module->body(), pos); | 1204 return factory()->NewModuleStatement(proxy, module->body(), pos); |
| 1207 } | 1205 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 | 1286 |
| 1289 | 1287 |
| 1290 Module* Parser::ParseModulePath(bool* ok) { | 1288 Module* Parser::ParseModulePath(bool* ok) { |
| 1291 // ModulePath: | 1289 // ModulePath: |
| 1292 // Identifier | 1290 // Identifier |
| 1293 // ModulePath '.' Identifier | 1291 // ModulePath '.' Identifier |
| 1294 | 1292 |
| 1295 int pos = peek_position(); | 1293 int pos = peek_position(); |
| 1296 Module* result = ParseModuleVariable(CHECK_OK); | 1294 Module* result = ParseModuleVariable(CHECK_OK); |
| 1297 while (Check(Token::PERIOD)) { | 1295 while (Check(Token::PERIOD)) { |
| 1298 const AstString* name = ParseIdentifierName(CHECK_OK); | 1296 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1299 #ifdef DEBUG | 1297 #ifdef DEBUG |
| 1300 if (FLAG_print_interface_details) | 1298 if (FLAG_print_interface_details) |
| 1301 PrintF("# Path .%.*s ", name->length(), name->raw_data()); | 1299 PrintF("# Path .%s ", name->ToAsciiArray()); |
| 1302 #endif | 1300 #endif |
| 1303 Module* member = factory()->NewModulePath(result, name, pos); | 1301 Module* member = factory()->NewModulePath(result, name, pos); |
| 1304 result->interface()->Add(name, member->interface(), zone(), ok); | 1302 result->interface()->Add(name, member->interface(), zone(), ok); |
| 1305 if (!*ok) { | 1303 if (!*ok) { |
| 1306 #ifdef DEBUG | 1304 #ifdef DEBUG |
| 1307 if (FLAG_print_interfaces) { | 1305 if (FLAG_print_interfaces) { |
| 1308 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); | 1306 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1309 PrintF("result: "); | 1307 PrintF("result: "); |
| 1310 result->interface()->Print(); | 1308 result->interface()->Print(); |
| 1311 PrintF("member: "); | 1309 PrintF("member: "); |
| 1312 member->interface()->Print(); | 1310 member->interface()->Print(); |
| 1313 } | 1311 } |
| 1314 #endif | 1312 #endif |
| 1315 ParserTraits::ReportMessage("invalid_module_path", name); | 1313 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1316 return NULL; | 1314 return NULL; |
| 1317 } | 1315 } |
| 1318 result = member; | 1316 result = member; |
| 1319 } | 1317 } |
| 1320 | 1318 |
| 1321 return result; | 1319 return result; |
| 1322 } | 1320 } |
| 1323 | 1321 |
| 1324 | 1322 |
| 1325 Module* Parser::ParseModuleVariable(bool* ok) { | 1323 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1326 // ModulePath: | 1324 // ModulePath: |
| 1327 // Identifier | 1325 // Identifier |
| 1328 | 1326 |
| 1329 int pos = peek_position(); | 1327 int pos = peek_position(); |
| 1330 const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1328 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1331 #ifdef DEBUG | 1329 #ifdef DEBUG |
| 1332 if (FLAG_print_interface_details) | 1330 if (FLAG_print_interface_details) |
| 1333 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); | 1331 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1334 #endif | 1332 #endif |
| 1335 VariableProxy* proxy = scope_->NewUnresolved( | 1333 VariableProxy* proxy = scope_->NewUnresolved( |
| 1336 factory(), name, Interface::NewModule(zone()), | 1334 factory(), name, Interface::NewModule(zone()), |
| 1337 scanner()->location().beg_pos); | 1335 scanner()->location().beg_pos); |
| 1338 | 1336 |
| 1339 return factory()->NewModuleVariable(proxy, pos); | 1337 return factory()->NewModuleVariable(proxy, pos); |
| 1340 } | 1338 } |
| 1341 | 1339 |
| 1342 | 1340 |
| 1343 Module* Parser::ParseModuleUrl(bool* ok) { | 1341 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1344 // Module: | 1342 // Module: |
| 1345 // String | 1343 // String |
| 1346 | 1344 |
| 1347 int pos = peek_position(); | 1345 int pos = peek_position(); |
| 1348 Expect(Token::STRING, CHECK_OK); | 1346 Expect(Token::STRING, CHECK_OK); |
| 1349 const AstString* symbol = GetSymbol(scanner()); | 1347 Handle<String> symbol = GetSymbol(); |
| 1350 | 1348 |
| 1351 // TODO(ES6): Request JS resource from environment... | 1349 // TODO(ES6): Request JS resource from environment... |
| 1352 | 1350 |
| 1353 #ifdef DEBUG | 1351 #ifdef DEBUG |
| 1354 if (FLAG_print_interface_details) PrintF("# Url "); | 1352 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1355 #endif | 1353 #endif |
| 1356 | 1354 |
| 1357 // Create an empty literal as long as the feature isn't finished. | 1355 // Create an empty literal as long as the feature isn't finished. |
| 1358 USE(symbol); | 1356 USE(symbol); |
| 1359 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1357 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1383 | 1381 |
| 1384 | 1382 |
| 1385 Block* Parser::ParseImportDeclaration(bool* ok) { | 1383 Block* Parser::ParseImportDeclaration(bool* ok) { |
| 1386 // ImportDeclaration: | 1384 // ImportDeclaration: |
| 1387 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1385 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1388 // | 1386 // |
| 1389 // TODO(ES6): implement destructuring ImportSpecifiers | 1387 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1390 | 1388 |
| 1391 int pos = peek_position(); | 1389 int pos = peek_position(); |
| 1392 Expect(Token::IMPORT, CHECK_OK); | 1390 Expect(Token::IMPORT, CHECK_OK); |
| 1393 ZoneList<const AstString*> names(1, zone()); | 1391 ZoneStringList names(1, zone()); |
| 1394 | 1392 |
| 1395 const AstString* name = ParseIdentifierName(CHECK_OK); | 1393 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1396 names.Add(name, zone()); | 1394 names.Add(name, zone()); |
| 1397 while (peek() == Token::COMMA) { | 1395 while (peek() == Token::COMMA) { |
| 1398 Consume(Token::COMMA); | 1396 Consume(Token::COMMA); |
| 1399 name = ParseIdentifierName(CHECK_OK); | 1397 name = ParseIdentifierName(CHECK_OK); |
| 1400 names.Add(name, zone()); | 1398 names.Add(name, zone()); |
| 1401 } | 1399 } |
| 1402 | 1400 |
| 1403 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1401 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1404 Module* module = ParseModuleSpecifier(CHECK_OK); | 1402 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1405 ExpectSemicolon(CHECK_OK); | 1403 ExpectSemicolon(CHECK_OK); |
| 1406 | 1404 |
| 1407 // Generate a separate declaration for each identifier. | 1405 // Generate a separate declaration for each identifier. |
| 1408 // TODO(ES6): once we implement destructuring, make that one declaration. | 1406 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1409 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1407 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 1410 for (int i = 0; i < names.length(); ++i) { | 1408 for (int i = 0; i < names.length(); ++i) { |
| 1411 #ifdef DEBUG | 1409 #ifdef DEBUG |
| 1412 if (FLAG_print_interface_details) | 1410 if (FLAG_print_interface_details) |
| 1413 PrintF("# Import %.*s ", name->length(), name->raw_data()); | 1411 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
| 1414 #endif | 1412 #endif |
| 1415 Interface* interface = Interface::NewUnknown(zone()); | 1413 Interface* interface = Interface::NewUnknown(zone()); |
| 1416 module->interface()->Add(names[i], interface, zone(), ok); | 1414 module->interface()->Add(names[i], interface, zone(), ok); |
| 1417 if (!*ok) { | 1415 if (!*ok) { |
| 1418 #ifdef DEBUG | 1416 #ifdef DEBUG |
| 1419 if (FLAG_print_interfaces) { | 1417 if (FLAG_print_interfaces) { |
| 1420 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), | 1418 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1421 name->raw_data()); | |
| 1422 PrintF("module: "); | 1419 PrintF("module: "); |
| 1423 module->interface()->Print(); | 1420 module->interface()->Print(); |
| 1424 } | 1421 } |
| 1425 #endif | 1422 #endif |
| 1426 ParserTraits::ReportMessage("invalid_module_path", name); | 1423 ParserTraits::ReportMessage("invalid_module_path", name); |
| 1427 return NULL; | 1424 return NULL; |
| 1428 } | 1425 } |
| 1429 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1426 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1430 Declaration* declaration = | 1427 Declaration* declaration = |
| 1431 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1428 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1442 // 'export' VariableDeclaration | 1439 // 'export' VariableDeclaration |
| 1443 // 'export' FunctionDeclaration | 1440 // 'export' FunctionDeclaration |
| 1444 // 'export' GeneratorDeclaration | 1441 // 'export' GeneratorDeclaration |
| 1445 // 'export' ModuleDeclaration | 1442 // 'export' ModuleDeclaration |
| 1446 // | 1443 // |
| 1447 // TODO(ES6): implement structuring ExportSpecifiers | 1444 // TODO(ES6): implement structuring ExportSpecifiers |
| 1448 | 1445 |
| 1449 Expect(Token::EXPORT, CHECK_OK); | 1446 Expect(Token::EXPORT, CHECK_OK); |
| 1450 | 1447 |
| 1451 Statement* result = NULL; | 1448 Statement* result = NULL; |
| 1452 ZoneList<const AstString*> names(1, zone()); | 1449 ZoneStringList names(1, zone()); |
| 1453 switch (peek()) { | 1450 switch (peek()) { |
| 1454 case Token::IDENTIFIER: { | 1451 case Token::IDENTIFIER: { |
| 1455 int pos = position(); | 1452 int pos = position(); |
| 1456 const AstString* name = | 1453 Handle<String> name = |
| 1457 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1454 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1458 // Handle 'module' as a context-sensitive keyword. | 1455 // Handle 'module' as a context-sensitive keyword. |
| 1459 if (name != ast_value_factory_->module_string()) { | 1456 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1460 names.Add(name, zone()); | 1457 names.Add(name, zone()); |
| 1461 while (peek() == Token::COMMA) { | 1458 while (peek() == Token::COMMA) { |
| 1462 Consume(Token::COMMA); | 1459 Consume(Token::COMMA); |
| 1463 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1460 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1464 names.Add(name, zone()); | 1461 names.Add(name, zone()); |
| 1465 } | 1462 } |
| 1466 ExpectSemicolon(CHECK_OK); | 1463 ExpectSemicolon(CHECK_OK); |
| 1467 result = factory()->NewEmptyStatement(pos); | 1464 result = factory()->NewEmptyStatement(pos); |
| 1468 } else { | 1465 } else { |
| 1469 result = ParseModuleDeclaration(&names, CHECK_OK); | 1466 result = ParseModuleDeclaration(&names, CHECK_OK); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1485 *ok = false; | 1482 *ok = false; |
| 1486 ReportUnexpectedToken(scanner()->current_token()); | 1483 ReportUnexpectedToken(scanner()->current_token()); |
| 1487 return NULL; | 1484 return NULL; |
| 1488 } | 1485 } |
| 1489 | 1486 |
| 1490 // Extract declared names into export declarations and interface. | 1487 // Extract declared names into export declarations and interface. |
| 1491 Interface* interface = scope_->interface(); | 1488 Interface* interface = scope_->interface(); |
| 1492 for (int i = 0; i < names.length(); ++i) { | 1489 for (int i = 0; i < names.length(); ++i) { |
| 1493 #ifdef DEBUG | 1490 #ifdef DEBUG |
| 1494 if (FLAG_print_interface_details) | 1491 if (FLAG_print_interface_details) |
| 1495 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); | 1492 PrintF("# Export %s ", names[i]->ToAsciiArray()); |
| 1496 #endif | 1493 #endif |
| 1497 Interface* inner = Interface::NewUnknown(zone()); | 1494 Interface* inner = Interface::NewUnknown(zone()); |
| 1498 interface->Add(names[i], inner, zone(), CHECK_OK); | 1495 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1499 if (!*ok) | 1496 if (!*ok) |
| 1500 return NULL; | 1497 return NULL; |
| 1501 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1498 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1502 USE(proxy); | 1499 USE(proxy); |
| 1503 // TODO(rossberg): Rethink whether we actually need to store export | 1500 // TODO(rossberg): Rethink whether we actually need to store export |
| 1504 // declarations (for compilation?). | 1501 // declarations (for compilation?). |
| 1505 // ExportDeclaration* declaration = | 1502 // ExportDeclaration* declaration = |
| 1506 // factory()->NewExportDeclaration(proxy, scope_, position); | 1503 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1507 // scope_->AddDeclaration(declaration); | 1504 // scope_->AddDeclaration(declaration); |
| 1508 } | 1505 } |
| 1509 | 1506 |
| 1510 ASSERT(result != NULL); | 1507 ASSERT(result != NULL); |
| 1511 return result; | 1508 return result; |
| 1512 } | 1509 } |
| 1513 | 1510 |
| 1514 | 1511 |
| 1515 Statement* Parser::ParseBlockElement(ZoneList<const AstString*>* labels, | 1512 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| 1516 bool* ok) { | 1513 bool* ok) { |
| 1517 // (Ecma 262 5th Edition, clause 14): | 1514 // (Ecma 262 5th Edition, clause 14): |
| 1518 // SourceElement: | 1515 // SourceElement: |
| 1519 // Statement | 1516 // Statement |
| 1520 // FunctionDeclaration | 1517 // FunctionDeclaration |
| 1521 // | 1518 // |
| 1522 // In harmony mode we allow additionally the following productions | 1519 // In harmony mode we allow additionally the following productions |
| 1523 // BlockElement (aka SourceElement): | 1520 // BlockElement (aka SourceElement): |
| 1524 // LetDeclaration | 1521 // LetDeclaration |
| 1525 // ConstDeclaration | 1522 // ConstDeclaration |
| 1526 // GeneratorDeclaration | 1523 // GeneratorDeclaration |
| 1527 | 1524 |
| 1528 switch (peek()) { | 1525 switch (peek()) { |
| 1529 case Token::FUNCTION: | 1526 case Token::FUNCTION: |
| 1530 return ParseFunctionDeclaration(NULL, ok); | 1527 return ParseFunctionDeclaration(NULL, ok); |
| 1531 case Token::LET: | 1528 case Token::LET: |
| 1532 case Token::CONST: | 1529 case Token::CONST: |
| 1533 return ParseVariableStatement(kModuleElement, NULL, ok); | 1530 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 1534 default: | 1531 default: |
| 1535 return ParseStatement(labels, ok); | 1532 return ParseStatement(labels, ok); |
| 1536 } | 1533 } |
| 1537 } | 1534 } |
| 1538 | 1535 |
| 1539 | 1536 |
| 1540 Statement* Parser::ParseStatement(ZoneList<const AstString*>* labels, | 1537 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
| 1541 bool* ok) { | |
| 1542 // Statement :: | 1538 // Statement :: |
| 1543 // Block | 1539 // Block |
| 1544 // VariableStatement | 1540 // VariableStatement |
| 1545 // EmptyStatement | 1541 // EmptyStatement |
| 1546 // ExpressionStatement | 1542 // ExpressionStatement |
| 1547 // IfStatement | 1543 // IfStatement |
| 1548 // IterationStatement | 1544 // IterationStatement |
| 1549 // ContinueStatement | 1545 // ContinueStatement |
| 1550 // BreakStatement | 1546 // BreakStatement |
| 1551 // ReturnStatement | 1547 // ReturnStatement |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 | 1637 |
| 1642 case Token::DEBUGGER: | 1638 case Token::DEBUGGER: |
| 1643 return ParseDebuggerStatement(ok); | 1639 return ParseDebuggerStatement(ok); |
| 1644 | 1640 |
| 1645 default: | 1641 default: |
| 1646 return ParseExpressionOrLabelledStatement(labels, ok); | 1642 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1647 } | 1643 } |
| 1648 } | 1644 } |
| 1649 | 1645 |
| 1650 | 1646 |
| 1651 VariableProxy* Parser::NewUnresolved(const AstString* name, VariableMode mode, | 1647 VariableProxy* Parser::NewUnresolved( |
| 1652 Interface* interface) { | 1648 Handle<String> name, VariableMode mode, Interface* interface) { |
| 1653 // If we are inside a function, a declaration of a var/const variable is a | 1649 // If we are inside a function, a declaration of a var/const variable is a |
| 1654 // truly local variable, and the scope of the variable is always the function | 1650 // truly local variable, and the scope of the variable is always the function |
| 1655 // scope. | 1651 // scope. |
| 1656 // Let/const variables in harmony mode are always added to the immediately | 1652 // Let/const variables in harmony mode are always added to the immediately |
| 1657 // enclosing scope. | 1653 // enclosing scope. |
| 1658 return DeclarationScope(mode)->NewUnresolved( | 1654 return DeclarationScope(mode)->NewUnresolved( |
| 1659 factory(), name, interface, position()); | 1655 factory(), name, interface, position()); |
| 1660 } | 1656 } |
| 1661 | 1657 |
| 1662 | 1658 |
| 1663 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1659 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1664 VariableProxy* proxy = declaration->proxy(); | 1660 VariableProxy* proxy = declaration->proxy(); |
| 1665 ASSERT(proxy->raw_name() != NULL); | 1661 Handle<String> name = proxy->name(); |
| 1666 const AstString* name = proxy->raw_name(); | |
| 1667 VariableMode mode = declaration->mode(); | 1662 VariableMode mode = declaration->mode(); |
| 1668 Scope* declaration_scope = DeclarationScope(mode); | 1663 Scope* declaration_scope = DeclarationScope(mode); |
| 1669 Variable* var = NULL; | 1664 Variable* var = NULL; |
| 1670 | 1665 |
| 1671 // If a suitable scope exists, then we can statically declare this | 1666 // If a suitable scope exists, then we can statically declare this |
| 1672 // 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 |
| 1673 // 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 |
| 1674 // to the corresponding activation frame at runtime if necessary. | 1669 // to the corresponding activation frame at runtime if necessary. |
| 1675 // For instance declarations inside an eval scope need to be added | 1670 // For instance declarations inside an eval scope need to be added |
| 1676 // to the calling function context. | 1671 // to the calling function context. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 // 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 |
| 1785 // initialization code. Thus, inside the 'with' statement, we need | 1780 // initialization code. Thus, inside the 'with' statement, we need |
| 1786 // both access to the static and the dynamic context chain; the | 1781 // both access to the static and the dynamic context chain; the |
| 1787 // runtime needs to provide both. | 1782 // runtime needs to provide both. |
| 1788 if (resolve && var != NULL) { | 1783 if (resolve && var != NULL) { |
| 1789 proxy->BindTo(var); | 1784 proxy->BindTo(var); |
| 1790 | 1785 |
| 1791 if (FLAG_harmony_modules) { | 1786 if (FLAG_harmony_modules) { |
| 1792 bool ok; | 1787 bool ok; |
| 1793 #ifdef DEBUG | 1788 #ifdef DEBUG |
| 1794 if (FLAG_print_interface_details) { | 1789 if (FLAG_print_interface_details) |
| 1795 PrintF("# Declare %.*s ", var->raw_name()->length(), | 1790 PrintF("# Declare %s\n", var->name()->ToAsciiArray()); |
| 1796 var->raw_name()->raw_data()); | |
| 1797 } | |
| 1798 #endif | 1791 #endif |
| 1799 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1792 proxy->interface()->Unify(var->interface(), zone(), &ok); |
| 1800 if (!ok) { | 1793 if (!ok) { |
| 1801 #ifdef DEBUG | 1794 #ifdef DEBUG |
| 1802 if (FLAG_print_interfaces) { | 1795 if (FLAG_print_interfaces) { |
| 1803 PrintF("DECLARE TYPE ERROR\n"); | 1796 PrintF("DECLARE TYPE ERROR\n"); |
| 1804 PrintF("proxy: "); | 1797 PrintF("proxy: "); |
| 1805 proxy->interface()->Print(); | 1798 proxy->interface()->Print(); |
| 1806 PrintF("var: "); | 1799 PrintF("var: "); |
| 1807 var->interface()->Print(); | 1800 var->interface()->Print(); |
| 1808 } | 1801 } |
| 1809 #endif | 1802 #endif |
| 1810 ParserTraits::ReportMessage("module_type_error", name); | 1803 ParserTraits::ReportMessage("module_type_error", name); |
| 1811 } | 1804 } |
| 1812 } | 1805 } |
| 1813 } | 1806 } |
| 1814 } | 1807 } |
| 1815 | 1808 |
| 1816 | 1809 |
| 1817 // Language extension which is only enabled for source files loaded | 1810 // Language extension which is only enabled for source files loaded |
| 1818 // through the API's extension mechanism. A native function | 1811 // through the API's extension mechanism. A native function |
| 1819 // declaration is resolved by looking up the function through a | 1812 // declaration is resolved by looking up the function through a |
| 1820 // callback provided by the extension. | 1813 // callback provided by the extension. |
| 1821 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1814 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1822 int pos = peek_position(); | 1815 int pos = peek_position(); |
| 1823 Expect(Token::FUNCTION, CHECK_OK); | 1816 Expect(Token::FUNCTION, CHECK_OK); |
| 1824 // Allow "eval" or "arguments" for backward compatibility. | 1817 // Allow "eval" or "arguments" for backward compatibility. |
| 1825 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1818 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1826 Expect(Token::LPAREN, CHECK_OK); | 1819 Expect(Token::LPAREN, CHECK_OK); |
| 1827 bool done = (peek() == Token::RPAREN); | 1820 bool done = (peek() == Token::RPAREN); |
| 1828 while (!done) { | 1821 while (!done) { |
| 1829 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1822 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1830 done = (peek() == Token::RPAREN); | 1823 done = (peek() == Token::RPAREN); |
| 1831 if (!done) { | 1824 if (!done) { |
| 1832 Expect(Token::COMMA, CHECK_OK); | 1825 Expect(Token::COMMA, CHECK_OK); |
| 1833 } | 1826 } |
| 1834 } | 1827 } |
| 1835 Expect(Token::RPAREN, CHECK_OK); | 1828 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1850 Declare(declaration, true, CHECK_OK); | 1843 Declare(declaration, true, CHECK_OK); |
| 1851 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1844 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1852 name, extension_, RelocInfo::kNoPosition); | 1845 name, extension_, RelocInfo::kNoPosition); |
| 1853 return factory()->NewExpressionStatement( | 1846 return factory()->NewExpressionStatement( |
| 1854 factory()->NewAssignment( | 1847 factory()->NewAssignment( |
| 1855 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1848 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1856 pos); | 1849 pos); |
| 1857 } | 1850 } |
| 1858 | 1851 |
| 1859 | 1852 |
| 1860 Statement* Parser::ParseFunctionDeclaration(ZoneList<const AstString*>* names, | 1853 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1861 bool* ok) { | |
| 1862 // FunctionDeclaration :: | 1854 // FunctionDeclaration :: |
| 1863 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1855 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1864 // GeneratorDeclaration :: | 1856 // GeneratorDeclaration :: |
| 1865 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1857 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1866 // '{' FunctionBody '}' | 1858 // '{' FunctionBody '}' |
| 1867 Expect(Token::FUNCTION, CHECK_OK); | 1859 Expect(Token::FUNCTION, CHECK_OK); |
| 1868 int pos = position(); | 1860 int pos = position(); |
| 1869 bool is_generator = allow_generators() && Check(Token::MUL); | 1861 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1870 bool is_strict_reserved = false; | 1862 bool is_strict_reserved = false; |
| 1871 const AstString* name = ParseIdentifierOrStrictReservedWord( | 1863 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1872 &is_strict_reserved, CHECK_OK); | 1864 &is_strict_reserved, CHECK_OK); |
| 1873 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1865 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1874 scanner()->location(), | 1866 scanner()->location(), |
| 1875 is_strict_reserved, | 1867 is_strict_reserved, |
| 1876 is_generator, | 1868 is_generator, |
| 1877 pos, | 1869 pos, |
| 1878 FunctionLiteral::DECLARATION, | 1870 FunctionLiteral::DECLARATION, |
| 1879 FunctionLiteral::NORMAL_ARITY, | 1871 FunctionLiteral::NORMAL_ARITY, |
| 1880 CHECK_OK); | 1872 CHECK_OK); |
| 1881 // Even if we're not at the top-level of the global or a function | 1873 // Even if we're not at the top-level of the global or a function |
| 1882 // scope, we treat it as such and introduce the function with its | 1874 // scope, we treat it as such and introduce the function with its |
| 1883 // initial value upon entering the corresponding scope. | 1875 // initial value upon entering the corresponding scope. |
| 1884 // In extended mode, a function behaves as a lexical binding, except in the | 1876 // In extended mode, a function behaves as a lexical binding, except in the |
| 1885 // global scope. | 1877 // global scope. |
| 1886 VariableMode mode = | 1878 VariableMode mode = |
| 1887 allow_harmony_scoping() && | 1879 allow_harmony_scoping() && |
| 1888 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| 1889 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1890 Declaration* declaration = | 1882 Declaration* declaration = |
| 1891 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1883 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1892 Declare(declaration, true, CHECK_OK); | 1884 Declare(declaration, true, CHECK_OK); |
| 1893 if (names) names->Add(name, zone()); | 1885 if (names) names->Add(name, zone()); |
| 1894 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1886 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1895 } | 1887 } |
| 1896 | 1888 |
| 1897 | 1889 |
| 1898 Block* Parser::ParseBlock(ZoneList<const AstString*>* labels, bool* ok) { | 1890 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1899 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 1891 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 1900 return ParseScopedBlock(labels, ok); | 1892 return ParseScopedBlock(labels, ok); |
| 1901 } | 1893 } |
| 1902 | 1894 |
| 1903 // Block :: | 1895 // Block :: |
| 1904 // '{' Statement* '}' | 1896 // '{' Statement* '}' |
| 1905 | 1897 |
| 1906 // Note that a Block does not introduce a new execution scope! | 1898 // Note that a Block does not introduce a new execution scope! |
| 1907 // (ECMA-262, 3rd, 12.2) | 1899 // (ECMA-262, 3rd, 12.2) |
| 1908 // | 1900 // |
| 1909 // Construct block expecting 16 statements. | 1901 // Construct block expecting 16 statements. |
| 1910 Block* result = | 1902 Block* result = |
| 1911 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1903 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1912 Target target(&this->target_stack_, result); | 1904 Target target(&this->target_stack_, result); |
| 1913 Expect(Token::LBRACE, CHECK_OK); | 1905 Expect(Token::LBRACE, CHECK_OK); |
| 1914 while (peek() != Token::RBRACE) { | 1906 while (peek() != Token::RBRACE) { |
| 1915 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1907 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1916 if (stat && !stat->IsEmpty()) { | 1908 if (stat && !stat->IsEmpty()) { |
| 1917 result->AddStatement(stat, zone()); | 1909 result->AddStatement(stat, zone()); |
| 1918 } | 1910 } |
| 1919 } | 1911 } |
| 1920 Expect(Token::RBRACE, CHECK_OK); | 1912 Expect(Token::RBRACE, CHECK_OK); |
| 1921 return result; | 1913 return result; |
| 1922 } | 1914 } |
| 1923 | 1915 |
| 1924 | 1916 |
| 1925 Block* Parser::ParseScopedBlock(ZoneList<const AstString*>* labels, bool* ok) { | 1917 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1926 // The harmony mode uses block elements instead of statements. | 1918 // The harmony mode uses block elements instead of statements. |
| 1927 // | 1919 // |
| 1928 // Block :: | 1920 // Block :: |
| 1929 // '{' BlockElement* '}' | 1921 // '{' BlockElement* '}' |
| 1930 | 1922 |
| 1931 // Construct block expecting 16 statements. | 1923 // Construct block expecting 16 statements. |
| 1932 Block* body = | 1924 Block* body = |
| 1933 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1925 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1934 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1926 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 1935 | 1927 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1950 } | 1942 } |
| 1951 Expect(Token::RBRACE, CHECK_OK); | 1943 Expect(Token::RBRACE, CHECK_OK); |
| 1952 block_scope->set_end_position(scanner()->location().end_pos); | 1944 block_scope->set_end_position(scanner()->location().end_pos); |
| 1953 block_scope = block_scope->FinalizeBlockScope(); | 1945 block_scope = block_scope->FinalizeBlockScope(); |
| 1954 body->set_scope(block_scope); | 1946 body->set_scope(block_scope); |
| 1955 return body; | 1947 return body; |
| 1956 } | 1948 } |
| 1957 | 1949 |
| 1958 | 1950 |
| 1959 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1951 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1960 ZoneList<const AstString*>* names, | 1952 ZoneStringList* names, |
| 1961 bool* ok) { | 1953 bool* ok) { |
| 1962 // VariableStatement :: | 1954 // VariableStatement :: |
| 1963 // VariableDeclarations ';' | 1955 // VariableDeclarations ';' |
| 1964 | 1956 |
| 1965 const AstString* ignore; | 1957 Handle<String> ignore; |
| 1966 Block* result = | 1958 Block* result = |
| 1967 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1959 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1968 ExpectSemicolon(CHECK_OK); | 1960 ExpectSemicolon(CHECK_OK); |
| 1969 return result; | 1961 return result; |
| 1970 } | 1962 } |
| 1971 | 1963 |
| 1972 | 1964 |
| 1973 // If the variable declaration declares exactly one non-const | 1965 // If the variable declaration declares exactly one non-const |
| 1974 // variable, then *out is set to that variable. In all other cases, | 1966 // variable, then *out is set to that variable. In all other cases, |
| 1975 // *out is untouched; in particular, it is the caller's responsibility | 1967 // *out is untouched; in particular, it is the caller's responsibility |
| 1976 // to initialize it properly. This mechanism is used for the parsing | 1968 // to initialize it properly. This mechanism is used for the parsing |
| 1977 // of 'for-in' loops. | 1969 // of 'for-in' loops. |
| 1978 Block* Parser::ParseVariableDeclarations( | 1970 Block* Parser::ParseVariableDeclarations( |
| 1979 VariableDeclarationContext var_context, | 1971 VariableDeclarationContext var_context, |
| 1980 VariableDeclarationProperties* decl_props, | 1972 VariableDeclarationProperties* decl_props, |
| 1981 ZoneList<const AstString*>* names, | 1973 ZoneStringList* names, |
| 1982 const AstString** out, | 1974 Handle<String>* out, |
| 1983 bool* ok) { | 1975 bool* ok) { |
| 1984 // VariableDeclarations :: | 1976 // VariableDeclarations :: |
| 1985 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 1977 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1986 // | 1978 // |
| 1987 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1979 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1988 // | 1980 // |
| 1989 // ConstDeclaration :: | 1981 // ConstDeclaration :: |
| 1990 // const ConstBinding (',' ConstBinding)* ';' | 1982 // const ConstBinding (',' ConstBinding)* ';' |
| 1991 // ConstBinding :: | 1983 // ConstBinding :: |
| 1992 // Identifier '=' AssignmentExpression | 1984 // Identifier '=' AssignmentExpression |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 // | 2072 // |
| 2081 // We mark the block as initializer block because we don't want the | 2073 // We mark the block as initializer block because we don't want the |
| 2082 // rewriter to add a '.result' assignment to such a block (to get compliant | 2074 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 2083 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2075 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 2084 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2076 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 2085 // is inside an initializer block, it is ignored. | 2077 // is inside an initializer block, it is ignored. |
| 2086 // | 2078 // |
| 2087 // Create new block with one expected declaration. | 2079 // Create new block with one expected declaration. |
| 2088 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2080 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 2089 int nvars = 0; // the number of variables declared | 2081 int nvars = 0; // the number of variables declared |
| 2090 const AstString* name = NULL; | 2082 Handle<String> name; |
| 2091 do { | 2083 do { |
| 2092 if (fni_ != NULL) fni_->Enter(); | 2084 if (fni_ != NULL) fni_->Enter(); |
| 2093 | 2085 |
| 2094 // Parse variable name. | 2086 // Parse variable name. |
| 2095 if (nvars > 0) Consume(Token::COMMA); | 2087 if (nvars > 0) Consume(Token::COMMA); |
| 2096 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2088 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2097 if (fni_ != NULL) fni_->PushVariableName(name); | 2089 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2098 | 2090 |
| 2099 // Declare variable. | 2091 // Declare variable. |
| 2100 // Note that we *always* must treat the initial value via a separate init | 2092 // 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... |
| 2199 // properties in the prototype chain, but only after the variable | 2191 // properties in the prototype chain, but only after the variable |
| 2200 // declaration statement has been executed. This is important in | 2192 // declaration statement has been executed. This is important in |
| 2201 // browsers where the global object (window) has lots of | 2193 // browsers where the global object (window) has lots of |
| 2202 // properties defined in prototype objects. | 2194 // properties defined in prototype objects. |
| 2203 if (initialization_scope->is_global_scope() && | 2195 if (initialization_scope->is_global_scope() && |
| 2204 !IsLexicalVariableMode(mode)) { | 2196 !IsLexicalVariableMode(mode)) { |
| 2205 // Compute the arguments for the runtime call. | 2197 // Compute the arguments for the runtime call. |
| 2206 ZoneList<Expression*>* arguments = | 2198 ZoneList<Expression*>* arguments = |
| 2207 new(zone()) ZoneList<Expression*>(3, zone()); | 2199 new(zone()) ZoneList<Expression*>(3, zone()); |
| 2208 // We have at least 1 parameter. | 2200 // We have at least 1 parameter. |
| 2209 arguments->Add(factory()->NewStringLiteral(name, pos), zone()); | 2201 arguments->Add(factory()->NewLiteral(name, pos), zone()); |
| 2210 CallRuntime* initialize; | 2202 CallRuntime* initialize; |
| 2211 | 2203 |
| 2212 if (is_const) { | 2204 if (is_const) { |
| 2213 arguments->Add(value, zone()); | 2205 arguments->Add(value, zone()); |
| 2214 value = NULL; // zap the value to avoid the unnecessary assignment | 2206 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2215 | 2207 |
| 2216 // Construct the call to Runtime_InitializeConstGlobal | 2208 // Construct the call to Runtime_InitializeConstGlobal |
| 2217 // and add it to the initialization statement block. | 2209 // and add it to the initialization statement block. |
| 2218 // Note that the function does different things depending on | 2210 // Note that the function does different things depending on |
| 2219 // the number of arguments (1 or 2). | 2211 // the number of arguments (1 or 2). |
| 2220 initialize = factory()->NewCallRuntime( | 2212 initialize = factory()->NewCallRuntime( |
| 2221 ast_value_factory_->initialize_const_global_string(), | 2213 isolate()->factory()->InitializeConstGlobal_string(), |
| 2222 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), | 2214 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
| 2223 arguments, pos); | 2215 arguments, pos); |
| 2224 } else { | 2216 } else { |
| 2225 // Add strict mode. | 2217 // Add strict mode. |
| 2226 // We may want to pass singleton to avoid Literal allocations. | 2218 // We may want to pass singleton to avoid Literal allocations. |
| 2227 StrictMode strict_mode = initialization_scope->strict_mode(); | 2219 StrictMode strict_mode = initialization_scope->strict_mode(); |
| 2228 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); | 2220 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
| 2229 | 2221 |
| 2230 // Be careful not to assign a value to the global variable if | 2222 // Be careful not to assign a value to the global variable if |
| 2231 // we're in a with. The initialization value should not | 2223 // we're in a with. The initialization value should not |
| 2232 // necessarily be stored in the global object in that case, | 2224 // necessarily be stored in the global object in that case, |
| 2233 // which is why we need to generate a separate assignment node. | 2225 // which is why we need to generate a separate assignment node. |
| 2234 if (value != NULL && !inside_with()) { | 2226 if (value != NULL && !inside_with()) { |
| 2235 arguments->Add(value, zone()); | 2227 arguments->Add(value, zone()); |
| 2236 value = NULL; // zap the value to avoid the unnecessary assignment | 2228 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2237 } | 2229 } |
| 2238 | 2230 |
| 2239 // Construct the call to Runtime_InitializeVarGlobal | 2231 // Construct the call to Runtime_InitializeVarGlobal |
| 2240 // and add it to the initialization statement block. | 2232 // and add it to the initialization statement block. |
| 2241 // Note that the function does different things depending on | 2233 // Note that the function does different things depending on |
| 2242 // the number of arguments (2 or 3). | 2234 // the number of arguments (2 or 3). |
| 2243 initialize = factory()->NewCallRuntime( | 2235 initialize = factory()->NewCallRuntime( |
| 2244 ast_value_factory_->initialize_var_global_string(), | 2236 isolate()->factory()->InitializeVarGlobal_string(), |
| 2245 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2237 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 2246 arguments, pos); | 2238 arguments, pos); |
| 2247 } | 2239 } |
| 2248 | 2240 |
| 2249 block->AddStatement( | 2241 block->AddStatement( |
| 2250 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), | 2242 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
| 2251 zone()); | 2243 zone()); |
| 2252 } else if (needs_init) { | 2244 } else if (needs_init) { |
| 2253 // Constant initializations always assign to the declared constant which | 2245 // Constant initializations always assign to the declared constant which |
| 2254 // is always at the function scope level. This is only relevant for | 2246 // 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... |
| 2290 // If there was a single non-const declaration, return it in the output | 2282 // If there was a single non-const declaration, return it in the output |
| 2291 // parameter for possible use by for/in. | 2283 // parameter for possible use by for/in. |
| 2292 if (nvars == 1 && !is_const) { | 2284 if (nvars == 1 && !is_const) { |
| 2293 *out = name; | 2285 *out = name; |
| 2294 } | 2286 } |
| 2295 | 2287 |
| 2296 return block; | 2288 return block; |
| 2297 } | 2289 } |
| 2298 | 2290 |
| 2299 | 2291 |
| 2300 static bool ContainsLabel(ZoneList<const AstString*>* labels, | 2292 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
| 2301 const AstString* label) { | 2293 ASSERT(!label.is_null()); |
| 2302 ASSERT(label != NULL); | |
| 2303 if (labels != NULL) { | 2294 if (labels != NULL) { |
| 2304 for (int i = labels->length(); i-- > 0; ) { | 2295 for (int i = labels->length(); i-- > 0; ) { |
| 2305 if (labels->at(i) == label) { | 2296 if (labels->at(i).is_identical_to(label)) { |
| 2306 return true; | 2297 return true; |
| 2307 } | 2298 } |
| 2308 } | 2299 } |
| 2309 } | 2300 } |
| 2310 return false; | 2301 return false; |
| 2311 } | 2302 } |
| 2312 | 2303 |
| 2313 | 2304 |
| 2314 Statement* Parser::ParseExpressionOrLabelledStatement( | 2305 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| 2315 ZoneList<const AstString*>* labels, bool* ok) { | 2306 bool* ok) { |
| 2316 // ExpressionStatement | LabelledStatement :: | 2307 // ExpressionStatement | LabelledStatement :: |
| 2317 // Expression ';' | 2308 // Expression ';' |
| 2318 // Identifier ':' Statement | 2309 // Identifier ':' Statement |
| 2319 int pos = peek_position(); | 2310 int pos = peek_position(); |
| 2320 bool starts_with_idenfifier = peek_any_identifier(); | 2311 bool starts_with_idenfifier = peek_any_identifier(); |
| 2321 Expression* expr = ParseExpression(true, CHECK_OK); | 2312 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2322 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2313 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
| 2323 expr->AsVariableProxy() != NULL && | 2314 expr->AsVariableProxy() != NULL && |
| 2324 !expr->AsVariableProxy()->is_this()) { | 2315 !expr->AsVariableProxy()->is_this()) { |
| 2325 // Expression is a single identifier, and not, e.g., a parenthesized | 2316 // Expression is a single identifier, and not, e.g., a parenthesized |
| 2326 // identifier. | 2317 // identifier. |
| 2327 VariableProxy* var = expr->AsVariableProxy(); | 2318 VariableProxy* var = expr->AsVariableProxy(); |
| 2328 const AstString* label = var->raw_name(); | 2319 Handle<String> label = var->name(); |
| 2329 // TODO(1240780): We don't check for redeclaration of labels | 2320 // TODO(1240780): We don't check for redeclaration of labels |
| 2330 // during preparsing since keeping track of the set of active | 2321 // during preparsing since keeping track of the set of active |
| 2331 // labels requires nontrivial changes to the way scopes are | 2322 // labels requires nontrivial changes to the way scopes are |
| 2332 // structured. However, these are probably changes we want to | 2323 // structured. However, these are probably changes we want to |
| 2333 // make later anyway so we should go back and fix this then. | 2324 // make later anyway so we should go back and fix this then. |
| 2334 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 2325 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
| 2335 ParserTraits::ReportMessage("label_redeclaration", label); | 2326 ParserTraits::ReportMessage("label_redeclaration", label); |
| 2336 *ok = false; | 2327 *ok = false; |
| 2337 return NULL; | 2328 return NULL; |
| 2338 } | 2329 } |
| 2339 if (labels == NULL) { | 2330 if (labels == NULL) { |
| 2340 labels = new(zone()) ZoneList<const AstString*>(4, zone()); | 2331 labels = new(zone()) ZoneStringList(4, zone()); |
| 2341 } | 2332 } |
| 2342 labels->Add(label, zone()); | 2333 labels->Add(label, zone()); |
| 2343 // Remove the "ghost" variable that turned out to be a label | 2334 // Remove the "ghost" variable that turned out to be a label |
| 2344 // from the top scope. This way, we don't try to resolve it | 2335 // from the top scope. This way, we don't try to resolve it |
| 2345 // during the scope processing. | 2336 // during the scope processing. |
| 2346 scope_->RemoveUnresolved(var); | 2337 scope_->RemoveUnresolved(var); |
| 2347 Expect(Token::COLON, CHECK_OK); | 2338 Expect(Token::COLON, CHECK_OK); |
| 2348 return ParseStatement(labels, ok); | 2339 return ParseStatement(labels, ok); |
| 2349 } | 2340 } |
| 2350 | 2341 |
| 2351 // If we have an extension, we allow a native function declaration. | 2342 // If we have an extension, we allow a native function declaration. |
| 2352 // A native function declaration starts with "native function" with | 2343 // A native function declaration starts with "native function" with |
| 2353 // no line-terminator between the two words. | 2344 // no line-terminator between the two words. |
| 2354 if (extension_ != NULL && | 2345 if (extension_ != NULL && |
| 2355 peek() == Token::FUNCTION && | 2346 peek() == Token::FUNCTION && |
| 2356 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2347 !scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2357 expr != NULL && | 2348 expr != NULL && |
| 2358 expr->AsVariableProxy() != NULL && | 2349 expr->AsVariableProxy() != NULL && |
| 2359 expr->AsVariableProxy()->raw_name() == | 2350 String::Equals(isolate()->factory()->native_string(), |
| 2360 ast_value_factory_->native_string() && | 2351 expr->AsVariableProxy()->name()) && |
| 2361 !scanner()->literal_contains_escapes()) { | 2352 !scanner()->literal_contains_escapes()) { |
| 2362 return ParseNativeDeclaration(ok); | 2353 return ParseNativeDeclaration(ok); |
| 2363 } | 2354 } |
| 2364 | 2355 |
| 2365 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2356 // Parsed expression statement, or the context-sensitive 'module' keyword. |
| 2366 // Only expect semicolon in the former case. | 2357 // Only expect semicolon in the former case. |
| 2367 if (!FLAG_harmony_modules || | 2358 if (!FLAG_harmony_modules || |
| 2368 peek() != Token::IDENTIFIER || | 2359 peek() != Token::IDENTIFIER || |
| 2369 scanner()->HasAnyLineTerminatorBeforeNext() || | 2360 scanner()->HasAnyLineTerminatorBeforeNext() || |
| 2370 expr->AsVariableProxy() == NULL || | 2361 expr->AsVariableProxy() == NULL || |
| 2371 expr->AsVariableProxy()->raw_name() != | 2362 !String::Equals(isolate()->factory()->module_string(), |
| 2372 ast_value_factory_->module_string() || | 2363 expr->AsVariableProxy()->name()) || |
| 2373 scanner()->literal_contains_escapes()) { | 2364 scanner()->literal_contains_escapes()) { |
| 2374 ExpectSemicolon(CHECK_OK); | 2365 ExpectSemicolon(CHECK_OK); |
| 2375 } | 2366 } |
| 2376 return factory()->NewExpressionStatement(expr, pos); | 2367 return factory()->NewExpressionStatement(expr, pos); |
| 2377 } | 2368 } |
| 2378 | 2369 |
| 2379 | 2370 |
| 2380 IfStatement* Parser::ParseIfStatement(ZoneList<const AstString*>* labels, | 2371 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2381 bool* ok) { | |
| 2382 // IfStatement :: | 2372 // IfStatement :: |
| 2383 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2373 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2384 | 2374 |
| 2385 int pos = peek_position(); | 2375 int pos = peek_position(); |
| 2386 Expect(Token::IF, CHECK_OK); | 2376 Expect(Token::IF, CHECK_OK); |
| 2387 Expect(Token::LPAREN, CHECK_OK); | 2377 Expect(Token::LPAREN, CHECK_OK); |
| 2388 Expression* condition = ParseExpression(true, CHECK_OK); | 2378 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2389 Expect(Token::RPAREN, CHECK_OK); | 2379 Expect(Token::RPAREN, CHECK_OK); |
| 2390 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2380 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2391 Statement* else_statement = NULL; | 2381 Statement* else_statement = NULL; |
| 2392 if (peek() == Token::ELSE) { | 2382 if (peek() == Token::ELSE) { |
| 2393 Next(); | 2383 Next(); |
| 2394 else_statement = ParseStatement(labels, CHECK_OK); | 2384 else_statement = ParseStatement(labels, CHECK_OK); |
| 2395 } else { | 2385 } else { |
| 2396 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2386 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2397 } | 2387 } |
| 2398 return factory()->NewIfStatement( | 2388 return factory()->NewIfStatement( |
| 2399 condition, then_statement, else_statement, pos); | 2389 condition, then_statement, else_statement, pos); |
| 2400 } | 2390 } |
| 2401 | 2391 |
| 2402 | 2392 |
| 2403 Statement* Parser::ParseContinueStatement(bool* ok) { | 2393 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2404 // ContinueStatement :: | 2394 // ContinueStatement :: |
| 2405 // 'continue' Identifier? ';' | 2395 // 'continue' Identifier? ';' |
| 2406 | 2396 |
| 2407 int pos = peek_position(); | 2397 int pos = peek_position(); |
| 2408 Expect(Token::CONTINUE, CHECK_OK); | 2398 Expect(Token::CONTINUE, CHECK_OK); |
| 2409 const AstString* label = NULL; | 2399 Handle<String> label = Handle<String>::null(); |
| 2410 Token::Value tok = peek(); | 2400 Token::Value tok = peek(); |
| 2411 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2401 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2412 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2402 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2413 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2403 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2414 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2404 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2415 } | 2405 } |
| 2416 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); | 2406 IterationStatement* target = NULL; |
| 2407 target = LookupContinueTarget(label, CHECK_OK); |
| 2417 if (target == NULL) { | 2408 if (target == NULL) { |
| 2418 // Illegal continue statement. | 2409 // Illegal continue statement. |
| 2419 const char* message = "illegal_continue"; | 2410 const char* message = "illegal_continue"; |
| 2420 if (label != NULL) { | 2411 if (!label.is_null()) { |
| 2421 message = "unknown_label"; | 2412 message = "unknown_label"; |
| 2422 } | 2413 } |
| 2423 ParserTraits::ReportMessage(message, label); | 2414 ParserTraits::ReportMessage(message, label); |
| 2424 *ok = false; | 2415 *ok = false; |
| 2425 return NULL; | 2416 return NULL; |
| 2426 } | 2417 } |
| 2427 ExpectSemicolon(CHECK_OK); | 2418 ExpectSemicolon(CHECK_OK); |
| 2428 return factory()->NewContinueStatement(target, pos); | 2419 return factory()->NewContinueStatement(target, pos); |
| 2429 } | 2420 } |
| 2430 | 2421 |
| 2431 | 2422 |
| 2432 Statement* Parser::ParseBreakStatement(ZoneList<const AstString*>* labels, | 2423 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2433 bool* ok) { | |
| 2434 // BreakStatement :: | 2424 // BreakStatement :: |
| 2435 // 'break' Identifier? ';' | 2425 // 'break' Identifier? ';' |
| 2436 | 2426 |
| 2437 int pos = peek_position(); | 2427 int pos = peek_position(); |
| 2438 Expect(Token::BREAK, CHECK_OK); | 2428 Expect(Token::BREAK, CHECK_OK); |
| 2439 const AstString* label = NULL; | 2429 Handle<String> label; |
| 2440 Token::Value tok = peek(); | 2430 Token::Value tok = peek(); |
| 2441 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2431 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2442 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2432 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2443 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2433 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2444 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2434 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2445 } | 2435 } |
| 2446 // Parse labeled break statements that target themselves into | 2436 // Parse labeled break statements that target themselves into |
| 2447 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2437 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2448 if (label != NULL && ContainsLabel(labels, label)) { | 2438 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2449 ExpectSemicolon(CHECK_OK); | 2439 ExpectSemicolon(CHECK_OK); |
| 2450 return factory()->NewEmptyStatement(pos); | 2440 return factory()->NewEmptyStatement(pos); |
| 2451 } | 2441 } |
| 2452 BreakableStatement* target = NULL; | 2442 BreakableStatement* target = NULL; |
| 2453 target = LookupBreakTarget(label, CHECK_OK); | 2443 target = LookupBreakTarget(label, CHECK_OK); |
| 2454 if (target == NULL) { | 2444 if (target == NULL) { |
| 2455 // Illegal break statement. | 2445 // Illegal break statement. |
| 2456 const char* message = "illegal_break"; | 2446 const char* message = "illegal_break"; |
| 2457 if (label != NULL) { | 2447 if (!label.is_null()) { |
| 2458 message = "unknown_label"; | 2448 message = "unknown_label"; |
| 2459 } | 2449 } |
| 2460 ParserTraits::ReportMessage(message, label); | 2450 ParserTraits::ReportMessage(message, label); |
| 2461 *ok = false; | 2451 *ok = false; |
| 2462 return NULL; | 2452 return NULL; |
| 2463 } | 2453 } |
| 2464 ExpectSemicolon(CHECK_OK); | 2454 ExpectSemicolon(CHECK_OK); |
| 2465 return factory()->NewBreakStatement(target, pos); | 2455 return factory()->NewBreakStatement(target, pos); |
| 2466 } | 2456 } |
| 2467 | 2457 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 Scope* decl_scope = scope_->DeclarationScope(); | 2491 Scope* decl_scope = scope_->DeclarationScope(); |
| 2502 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { | 2492 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
| 2503 ReportMessageAt(loc, "illegal_return"); | 2493 ReportMessageAt(loc, "illegal_return"); |
| 2504 *ok = false; | 2494 *ok = false; |
| 2505 return NULL; | 2495 return NULL; |
| 2506 } | 2496 } |
| 2507 return result; | 2497 return result; |
| 2508 } | 2498 } |
| 2509 | 2499 |
| 2510 | 2500 |
| 2511 Statement* Parser::ParseWithStatement(ZoneList<const AstString*>* labels, | 2501 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2512 bool* ok) { | |
| 2513 // WithStatement :: | 2502 // WithStatement :: |
| 2514 // 'with' '(' Expression ')' Statement | 2503 // 'with' '(' Expression ')' Statement |
| 2515 | 2504 |
| 2516 Expect(Token::WITH, CHECK_OK); | 2505 Expect(Token::WITH, CHECK_OK); |
| 2517 int pos = position(); | 2506 int pos = position(); |
| 2518 | 2507 |
| 2519 if (strict_mode() == STRICT) { | 2508 if (strict_mode() == STRICT) { |
| 2520 ReportMessage("strict_mode_with"); | 2509 ReportMessage("strict_mode_with"); |
| 2521 *ok = false; | 2510 *ok = false; |
| 2522 return NULL; | 2511 return NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 peek() != Token::DEFAULT && | 2553 peek() != Token::DEFAULT && |
| 2565 peek() != Token::RBRACE) { | 2554 peek() != Token::RBRACE) { |
| 2566 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2555 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2567 statements->Add(stat, zone()); | 2556 statements->Add(stat, zone()); |
| 2568 } | 2557 } |
| 2569 | 2558 |
| 2570 return factory()->NewCaseClause(label, statements, pos); | 2559 return factory()->NewCaseClause(label, statements, pos); |
| 2571 } | 2560 } |
| 2572 | 2561 |
| 2573 | 2562 |
| 2574 SwitchStatement* Parser::ParseSwitchStatement( | 2563 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| 2575 ZoneList<const AstString*>* labels, bool* ok) { | 2564 bool* ok) { |
| 2576 // SwitchStatement :: | 2565 // SwitchStatement :: |
| 2577 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2566 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2578 | 2567 |
| 2579 SwitchStatement* statement = | 2568 SwitchStatement* statement = |
| 2580 factory()->NewSwitchStatement(labels, peek_position()); | 2569 factory()->NewSwitchStatement(labels, peek_position()); |
| 2581 Target target(&this->target_stack_, statement); | 2570 Target target(&this->target_stack_, statement); |
| 2582 | 2571 |
| 2583 Expect(Token::SWITCH, CHECK_OK); | 2572 Expect(Token::SWITCH, CHECK_OK); |
| 2584 Expect(Token::LPAREN, CHECK_OK); | 2573 Expect(Token::LPAREN, CHECK_OK); |
| 2585 Expression* tag = ParseExpression(true, CHECK_OK); | 2574 Expression* tag = ParseExpression(true, CHECK_OK); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2648 } | 2637 } |
| 2649 | 2638 |
| 2650 // If we can break out from the catch block and there is a finally block, | 2639 // If we can break out from the catch block and there is a finally block, |
| 2651 // then we will need to collect escaping targets from the catch | 2640 // then we will need to collect escaping targets from the catch |
| 2652 // block. Since we don't know yet if there will be a finally block, we | 2641 // block. Since we don't know yet if there will be a finally block, we |
| 2653 // always collect the targets. | 2642 // always collect the targets. |
| 2654 TargetCollector catch_collector(zone()); | 2643 TargetCollector catch_collector(zone()); |
| 2655 Scope* catch_scope = NULL; | 2644 Scope* catch_scope = NULL; |
| 2656 Variable* catch_variable = NULL; | 2645 Variable* catch_variable = NULL; |
| 2657 Block* catch_block = NULL; | 2646 Block* catch_block = NULL; |
| 2658 const AstString* name = NULL; | 2647 Handle<String> name; |
| 2659 if (tok == Token::CATCH) { | 2648 if (tok == Token::CATCH) { |
| 2660 Consume(Token::CATCH); | 2649 Consume(Token::CATCH); |
| 2661 | 2650 |
| 2662 Expect(Token::LPAREN, CHECK_OK); | 2651 Expect(Token::LPAREN, CHECK_OK); |
| 2663 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2652 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2664 catch_scope->set_start_position(scanner()->location().beg_pos); | 2653 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2665 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2654 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2666 | 2655 |
| 2667 Expect(Token::RPAREN, CHECK_OK); | 2656 Expect(Token::RPAREN, CHECK_OK); |
| 2668 | 2657 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2718 index, try_block, finally_block, pos); | 2707 index, try_block, finally_block, pos); |
| 2719 // Combine the jump targets of the try block and the possible catch block. | 2708 // Combine the jump targets of the try block and the possible catch block. |
| 2720 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2709 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2721 } | 2710 } |
| 2722 | 2711 |
| 2723 result->set_escaping_targets(try_collector.targets()); | 2712 result->set_escaping_targets(try_collector.targets()); |
| 2724 return result; | 2713 return result; |
| 2725 } | 2714 } |
| 2726 | 2715 |
| 2727 | 2716 |
| 2728 DoWhileStatement* Parser::ParseDoWhileStatement( | 2717 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2729 ZoneList<const AstString*>* labels, bool* ok) { | 2718 bool* ok) { |
| 2730 // DoStatement :: | 2719 // DoStatement :: |
| 2731 // 'do' Statement 'while' '(' Expression ')' ';' | 2720 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2732 | 2721 |
| 2733 DoWhileStatement* loop = | 2722 DoWhileStatement* loop = |
| 2734 factory()->NewDoWhileStatement(labels, peek_position()); | 2723 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2735 Target target(&this->target_stack_, loop); | 2724 Target target(&this->target_stack_, loop); |
| 2736 | 2725 |
| 2737 Expect(Token::DO, CHECK_OK); | 2726 Expect(Token::DO, CHECK_OK); |
| 2738 Statement* body = ParseStatement(NULL, CHECK_OK); | 2727 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2739 Expect(Token::WHILE, CHECK_OK); | 2728 Expect(Token::WHILE, CHECK_OK); |
| 2740 Expect(Token::LPAREN, CHECK_OK); | 2729 Expect(Token::LPAREN, CHECK_OK); |
| 2741 | 2730 |
| 2742 Expression* cond = ParseExpression(true, CHECK_OK); | 2731 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2743 Expect(Token::RPAREN, CHECK_OK); | 2732 Expect(Token::RPAREN, CHECK_OK); |
| 2744 | 2733 |
| 2745 // Allow do-statements to be terminated with and without | 2734 // Allow do-statements to be terminated with and without |
| 2746 // semi-colons. This allows code such as 'do;while(0)return' to | 2735 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2747 // parse, which would not be the case if we had used the | 2736 // parse, which would not be the case if we had used the |
| 2748 // ExpectSemicolon() functionality here. | 2737 // ExpectSemicolon() functionality here. |
| 2749 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2738 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2750 | 2739 |
| 2751 if (loop != NULL) loop->Initialize(cond, body); | 2740 if (loop != NULL) loop->Initialize(cond, body); |
| 2752 return loop; | 2741 return loop; |
| 2753 } | 2742 } |
| 2754 | 2743 |
| 2755 | 2744 |
| 2756 WhileStatement* Parser::ParseWhileStatement(ZoneList<const AstString*>* labels, | 2745 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2757 bool* ok) { | |
| 2758 // WhileStatement :: | 2746 // WhileStatement :: |
| 2759 // 'while' '(' Expression ')' Statement | 2747 // 'while' '(' Expression ')' Statement |
| 2760 | 2748 |
| 2761 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); | 2749 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2762 Target target(&this->target_stack_, loop); | 2750 Target target(&this->target_stack_, loop); |
| 2763 | 2751 |
| 2764 Expect(Token::WHILE, CHECK_OK); | 2752 Expect(Token::WHILE, CHECK_OK); |
| 2765 Expect(Token::LPAREN, CHECK_OK); | 2753 Expect(Token::LPAREN, CHECK_OK); |
| 2766 Expression* cond = ParseExpression(true, CHECK_OK); | 2754 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2767 Expect(Token::RPAREN, CHECK_OK); | 2755 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2786 } | 2774 } |
| 2787 | 2775 |
| 2788 | 2776 |
| 2789 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2777 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2790 Expression* each, | 2778 Expression* each, |
| 2791 Expression* subject, | 2779 Expression* subject, |
| 2792 Statement* body) { | 2780 Statement* body) { |
| 2793 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2781 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2794 | 2782 |
| 2795 if (for_of != NULL) { | 2783 if (for_of != NULL) { |
| 2784 Factory* heap_factory = isolate()->factory(); |
| 2796 Variable* iterable = scope_->DeclarationScope()->NewTemporary( | 2785 Variable* iterable = scope_->DeclarationScope()->NewTemporary( |
| 2797 ast_value_factory_->dot_iterable_string()); | 2786 heap_factory->dot_iterable_string()); |
| 2798 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2787 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
| 2799 ast_value_factory_->dot_iterator_string()); | 2788 heap_factory->dot_iterator_string()); |
| 2800 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2789 Variable* result = scope_->DeclarationScope()->NewTemporary( |
| 2801 ast_value_factory_->dot_result_string()); | 2790 heap_factory->dot_result_string()); |
| 2802 | 2791 |
| 2803 Expression* assign_iterable; | 2792 Expression* assign_iterable; |
| 2804 Expression* assign_iterator; | 2793 Expression* assign_iterator; |
| 2805 Expression* next_result; | 2794 Expression* next_result; |
| 2806 Expression* result_done; | 2795 Expression* result_done; |
| 2807 Expression* assign_each; | 2796 Expression* assign_each; |
| 2808 | 2797 |
| 2809 // var iterable = subject; | 2798 // var iterable = subject; |
| 2810 { | 2799 { |
| 2811 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); | 2800 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); |
| 2812 assign_iterable = factory()->NewAssignment( | 2801 assign_iterable = factory()->NewAssignment( |
| 2813 Token::ASSIGN, iterable_proxy, subject, subject->position()); | 2802 Token::ASSIGN, iterable_proxy, subject, subject->position()); |
| 2814 } | 2803 } |
| 2815 | 2804 |
| 2816 // var iterator = iterable[Symbol.iterator](); | 2805 // var iterator = iterable[Symbol.iterator](); |
| 2817 { | 2806 { |
| 2818 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); | 2807 Expression* iterable_proxy = factory()->NewVariableProxy(iterable); |
| 2819 Expression* iterator_symbol_literal = | 2808 Handle<Symbol> iterator_symbol( |
| 2820 factory()->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); | 2809 isolate()->native_context()->iterator_symbol(), isolate()); |
| 2810 Expression* iterator_symbol_literal = factory()->NewLiteral( |
| 2811 iterator_symbol, RelocInfo::kNoPosition); |
| 2821 // FIXME(wingo): Unhappily, it will be a common error that the RHS of a | 2812 // FIXME(wingo): Unhappily, it will be a common error that the RHS of a |
| 2822 // for-of doesn't have a Symbol.iterator property. We should do better | 2813 // for-of doesn't have a Symbol.iterator property. We should do better |
| 2823 // than informing the user that "undefined is not a function". | 2814 // than informing the user that "undefined is not a function". |
| 2824 int pos = subject->position(); | 2815 int pos = subject->position(); |
| 2825 Expression* iterator_property = factory()->NewProperty( | 2816 Expression* iterator_property = factory()->NewProperty( |
| 2826 iterable_proxy, iterator_symbol_literal, pos); | 2817 iterable_proxy, iterator_symbol_literal, pos); |
| 2827 ZoneList<Expression*>* iterator_arguments = | 2818 ZoneList<Expression*>* iterator_arguments = |
| 2828 new(zone()) ZoneList<Expression*>(0, zone()); | 2819 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2829 Expression* iterator_call = factory()->NewCall( | 2820 Expression* iterator_call = factory()->NewCall( |
| 2830 iterator_property, iterator_arguments, pos); | 2821 iterator_property, iterator_arguments, pos); |
| 2831 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2822 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2832 assign_iterator = factory()->NewAssignment( | 2823 assign_iterator = factory()->NewAssignment( |
| 2833 Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition); | 2824 Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition); |
| 2834 } | 2825 } |
| 2835 | 2826 |
| 2836 // var result = iterator.next(); | 2827 // var result = iterator.next(); |
| 2837 { | 2828 { |
| 2838 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2829 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2839 Expression* next_literal = factory()->NewStringLiteral( | 2830 Expression* next_literal = factory()->NewLiteral( |
| 2840 ast_value_factory_->next_string(), RelocInfo::kNoPosition); | 2831 heap_factory->next_string(), RelocInfo::kNoPosition); |
| 2841 Expression* next_property = factory()->NewProperty( | 2832 Expression* next_property = factory()->NewProperty( |
| 2842 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2833 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| 2843 ZoneList<Expression*>* next_arguments = | 2834 ZoneList<Expression*>* next_arguments = |
| 2844 new(zone()) ZoneList<Expression*>(0, zone()); | 2835 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2845 Expression* next_call = factory()->NewCall( | 2836 Expression* next_call = factory()->NewCall( |
| 2846 next_property, next_arguments, RelocInfo::kNoPosition); | 2837 next_property, next_arguments, RelocInfo::kNoPosition); |
| 2847 Expression* result_proxy = factory()->NewVariableProxy(result); | 2838 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2848 next_result = factory()->NewAssignment( | 2839 next_result = factory()->NewAssignment( |
| 2849 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2840 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
| 2850 } | 2841 } |
| 2851 | 2842 |
| 2852 // result.done | 2843 // result.done |
| 2853 { | 2844 { |
| 2854 Expression* done_literal = factory()->NewStringLiteral( | 2845 Expression* done_literal = factory()->NewLiteral( |
| 2855 ast_value_factory_->done_string(), RelocInfo::kNoPosition); | 2846 heap_factory->done_string(), RelocInfo::kNoPosition); |
| 2856 Expression* result_proxy = factory()->NewVariableProxy(result); | 2847 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2857 result_done = factory()->NewProperty( | 2848 result_done = factory()->NewProperty( |
| 2858 result_proxy, done_literal, RelocInfo::kNoPosition); | 2849 result_proxy, done_literal, RelocInfo::kNoPosition); |
| 2859 } | 2850 } |
| 2860 | 2851 |
| 2861 // each = result.value | 2852 // each = result.value |
| 2862 { | 2853 { |
| 2863 Expression* value_literal = factory()->NewStringLiteral( | 2854 Expression* value_literal = factory()->NewLiteral( |
| 2864 ast_value_factory_->value_string(), RelocInfo::kNoPosition); | 2855 heap_factory->value_string(), RelocInfo::kNoPosition); |
| 2865 Expression* result_proxy = factory()->NewVariableProxy(result); | 2856 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2866 Expression* result_value = factory()->NewProperty( | 2857 Expression* result_value = factory()->NewProperty( |
| 2867 result_proxy, value_literal, RelocInfo::kNoPosition); | 2858 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 2868 assign_each = factory()->NewAssignment( | 2859 assign_each = factory()->NewAssignment( |
| 2869 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2860 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
| 2870 } | 2861 } |
| 2871 | 2862 |
| 2872 for_of->Initialize(each, subject, body, | 2863 for_of->Initialize(each, subject, body, |
| 2873 assign_iterable, | 2864 assign_iterable, |
| 2874 assign_iterator, | 2865 assign_iterator, |
| 2875 next_result, | 2866 next_result, |
| 2876 result_done, | 2867 result_done, |
| 2877 assign_each); | 2868 assign_each); |
| 2878 } else { | 2869 } else { |
| 2879 stmt->Initialize(each, subject, body); | 2870 stmt->Initialize(each, subject, body); |
| 2880 } | 2871 } |
| 2881 } | 2872 } |
| 2882 | 2873 |
| 2883 | 2874 |
| 2884 Statement* Parser::DesugarLetBindingsInForStatement( | 2875 Statement* Parser::DesugarLetBindingsInForStatement( |
| 2885 Scope* inner_scope, ZoneList<const AstString*>* names, | 2876 Scope* inner_scope, ZoneStringList* names, ForStatement* loop, |
| 2886 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2877 Statement* init, Expression* cond, Statement* next, Statement* body, |
| 2887 Statement* body, bool* ok) { | 2878 bool* ok) { |
| 2888 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are | 2879 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are |
| 2889 // copied into a new environment. After copying, the "next" statement of the | 2880 // copied into a new environment. After copying, the "next" statement of the |
| 2890 // loop is executed to update the loop variables. The loop condition is | 2881 // loop is executed to update the loop variables. The loop condition is |
| 2891 // checked and the loop body is executed. | 2882 // checked and the loop body is executed. |
| 2892 // | 2883 // |
| 2893 // We rewrite a for statement of the form | 2884 // We rewrite a for statement of the form |
| 2894 // | 2885 // |
| 2895 // for (let x = i; cond; next) body | 2886 // for (let x = i; cond; next) body |
| 2896 // | 2887 // |
| 2897 // into | 2888 // into |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2918 // } | 2909 // } |
| 2919 | 2910 |
| 2920 ASSERT(names->length() > 0); | 2911 ASSERT(names->length() > 0); |
| 2921 Scope* for_scope = scope_; | 2912 Scope* for_scope = scope_; |
| 2922 ZoneList<Variable*> temps(names->length(), zone()); | 2913 ZoneList<Variable*> temps(names->length(), zone()); |
| 2923 | 2914 |
| 2924 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, | 2915 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false, |
| 2925 RelocInfo::kNoPosition); | 2916 RelocInfo::kNoPosition); |
| 2926 outer_block->AddStatement(init, zone()); | 2917 outer_block->AddStatement(init, zone()); |
| 2927 | 2918 |
| 2928 const AstString* temp_name = ast_value_factory_->dot_for_string(); | 2919 Handle<String> temp_name = isolate()->factory()->dot_for_string(); |
| 2920 Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate()); |
| 2921 Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate()); |
| 2922 |
| 2929 | 2923 |
| 2930 // For each let variable x: | 2924 // For each let variable x: |
| 2931 // make statement: temp_x = x. | 2925 // make statement: temp_x = x. |
| 2932 for (int i = 0; i < names->length(); i++) { | 2926 for (int i = 0; i < names->length(); i++) { |
| 2933 VariableProxy* proxy = | 2927 VariableProxy* proxy = |
| 2934 NewUnresolved(names->at(i), LET, Interface::NewValue()); | 2928 NewUnresolved(names->at(i), LET, Interface::NewValue()); |
| 2935 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); | 2929 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name); |
| 2936 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2930 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2937 Assignment* assignment = factory()->NewAssignment( | 2931 Assignment* assignment = factory()->NewAssignment( |
| 2938 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); | 2932 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); |
| 2939 Statement* assignment_statement = factory()->NewExpressionStatement( | 2933 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2940 assignment, RelocInfo::kNoPosition); | 2934 assignment, RelocInfo::kNoPosition); |
| 2941 outer_block->AddStatement(assignment_statement, zone()); | 2935 outer_block->AddStatement(assignment_statement, zone()); |
| 2942 temps.Add(temp, zone()); | 2936 temps.Add(temp, zone()); |
| 2943 } | 2937 } |
| 2944 | 2938 |
| 2945 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); | 2939 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); |
| 2946 // Make statement: flag = 1. | 2940 // Make statement: flag = 1. |
| 2947 { | 2941 { |
| 2948 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2942 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2949 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); | 2943 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); |
| 2950 Assignment* assignment = factory()->NewAssignment( | 2944 Assignment* assignment = factory()->NewAssignment( |
| 2951 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); | 2945 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); |
| 2952 Statement* assignment_statement = factory()->NewExpressionStatement( | 2946 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2953 assignment, RelocInfo::kNoPosition); | 2947 assignment, RelocInfo::kNoPosition); |
| 2954 outer_block->AddStatement(assignment_statement, zone()); | 2948 outer_block->AddStatement(assignment_statement, zone()); |
| 2955 } | 2949 } |
| 2956 | 2950 |
| 2957 outer_block->AddStatement(loop, zone()); | 2951 outer_block->AddStatement(loop, zone()); |
| 2958 outer_block->set_scope(for_scope); | 2952 outer_block->set_scope(for_scope); |
| 2959 scope_ = inner_scope; | 2953 scope_ = inner_scope; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2979 assignment, pos); | 2973 assignment, pos); |
| 2980 proxy->var()->set_initializer_position(pos); | 2974 proxy->var()->set_initializer_position(pos); |
| 2981 inner_block->AddStatement(assignment_statement, zone()); | 2975 inner_block->AddStatement(assignment_statement, zone()); |
| 2982 } | 2976 } |
| 2983 | 2977 |
| 2984 // Make statement: if (flag == 1) { flag = 0; } else { next; }. | 2978 // Make statement: if (flag == 1) { flag = 0; } else { next; }. |
| 2985 { | 2979 { |
| 2986 Expression* compare = NULL; | 2980 Expression* compare = NULL; |
| 2987 // Make compare expresion: flag == 1. | 2981 // Make compare expresion: flag == 1. |
| 2988 { | 2982 { |
| 2989 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); | 2983 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); |
| 2990 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2984 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2991 compare = factory()->NewCompareOperation( | 2985 compare = factory()->NewCompareOperation( |
| 2992 Token::EQ, flag_proxy, const1, pos); | 2986 Token::EQ, flag_proxy, const1, pos); |
| 2993 } | 2987 } |
| 2994 Statement* clear_flag = NULL; | 2988 Statement* clear_flag = NULL; |
| 2995 // Make statement: flag = 0. | 2989 // Make statement: flag = 0. |
| 2996 { | 2990 { |
| 2997 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); | 2991 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| 2998 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); | 2992 Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition); |
| 2999 Assignment* assignment = factory()->NewAssignment( | 2993 Assignment* assignment = factory()->NewAssignment( |
| 3000 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); | 2994 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); |
| 3001 clear_flag = factory()->NewExpressionStatement(assignment, pos); | 2995 clear_flag = factory()->NewExpressionStatement(assignment, pos); |
| 3002 } | 2996 } |
| 3003 Statement* clear_flag_or_next = factory()->NewIfStatement( | 2997 Statement* clear_flag_or_next = factory()->NewIfStatement( |
| 3004 compare, clear_flag, next, RelocInfo::kNoPosition); | 2998 compare, clear_flag, next, RelocInfo::kNoPosition); |
| 3005 inner_block->AddStatement(clear_flag_or_next, zone()); | 2999 inner_block->AddStatement(clear_flag_or_next, zone()); |
| 3006 } | 3000 } |
| 3007 | 3001 |
| 3008 | 3002 |
| 3009 // Make statement: if (cond) { } else { break; }. | 3003 // Make statement: if (cond) { } else { break; }. |
| 3010 { | 3004 { |
| 3011 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 3005 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 3012 BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); | 3006 BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK); |
| 3013 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); | 3007 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); |
| 3014 Statement* if_not_cond_break = factory()->NewIfStatement( | 3008 Statement* if_not_cond_break = factory()->NewIfStatement( |
| 3015 cond, empty, stop, cond->position()); | 3009 cond, empty, stop, cond->position()); |
| 3016 inner_block->AddStatement(if_not_cond_break, zone()); | 3010 inner_block->AddStatement(if_not_cond_break, zone()); |
| 3017 } | 3011 } |
| 3018 | 3012 |
| 3019 inner_block->AddStatement(body, zone()); | 3013 inner_block->AddStatement(body, zone()); |
| 3020 | 3014 |
| 3021 // For each let variable x: | 3015 // For each let variable x: |
| 3022 // make statement: temp_x = x; | 3016 // make statement: temp_x = x; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3033 | 3027 |
| 3034 inner_scope->set_end_position(scanner()->location().end_pos); | 3028 inner_scope->set_end_position(scanner()->location().end_pos); |
| 3035 inner_block->set_scope(inner_scope); | 3029 inner_block->set_scope(inner_scope); |
| 3036 scope_ = for_scope; | 3030 scope_ = for_scope; |
| 3037 | 3031 |
| 3038 loop->Initialize(NULL, NULL, NULL, inner_block); | 3032 loop->Initialize(NULL, NULL, NULL, inner_block); |
| 3039 return outer_block; | 3033 return outer_block; |
| 3040 } | 3034 } |
| 3041 | 3035 |
| 3042 | 3036 |
| 3043 Statement* Parser::ParseForStatement(ZoneList<const AstString*>* labels, | 3037 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 3044 bool* ok) { | |
| 3045 // ForStatement :: | 3038 // ForStatement :: |
| 3046 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3039 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 3047 | 3040 |
| 3048 int pos = peek_position(); | 3041 int pos = peek_position(); |
| 3049 Statement* init = NULL; | 3042 Statement* init = NULL; |
| 3050 ZoneList<const AstString*> let_bindings(1, zone()); | 3043 ZoneStringList let_bindings(1, zone()); |
| 3051 | 3044 |
| 3052 // Create an in-between scope for let-bound iteration variables. | 3045 // Create an in-between scope for let-bound iteration variables. |
| 3053 Scope* saved_scope = scope_; | 3046 Scope* saved_scope = scope_; |
| 3054 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3047 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3055 scope_ = for_scope; | 3048 scope_ = for_scope; |
| 3056 | 3049 |
| 3057 Expect(Token::FOR, CHECK_OK); | 3050 Expect(Token::FOR, CHECK_OK); |
| 3058 Expect(Token::LPAREN, CHECK_OK); | 3051 Expect(Token::LPAREN, CHECK_OK); |
| 3059 for_scope->set_start_position(scanner()->location().beg_pos); | 3052 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3060 if (peek() != Token::SEMICOLON) { | 3053 if (peek() != Token::SEMICOLON) { |
| 3061 if (peek() == Token::VAR || peek() == Token::CONST) { | 3054 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 3062 bool is_const = peek() == Token::CONST; | 3055 bool is_const = peek() == Token::CONST; |
| 3063 const AstString* name = NULL; | 3056 Handle<String> name; |
| 3064 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3057 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3065 Block* variable_statement = | 3058 Block* variable_statement = |
| 3066 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3059 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 3067 CHECK_OK); | 3060 CHECK_OK); |
| 3068 bool accept_OF = decl_props == kHasNoInitializers; | 3061 bool accept_OF = decl_props == kHasNoInitializers; |
| 3069 ForEachStatement::VisitMode mode; | 3062 ForEachStatement::VisitMode mode; |
| 3070 | 3063 |
| 3071 if (name != NULL && CheckInOrOf(accept_OF, &mode)) { | 3064 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
| 3072 Interface* interface = | 3065 Interface* interface = |
| 3073 is_const ? Interface::NewConst() : Interface::NewValue(); | 3066 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 3074 ForEachStatement* loop = | 3067 ForEachStatement* loop = |
| 3075 factory()->NewForEachStatement(mode, labels, pos); | 3068 factory()->NewForEachStatement(mode, labels, pos); |
| 3076 Target target(&this->target_stack_, loop); | 3069 Target target(&this->target_stack_, loop); |
| 3077 | 3070 |
| 3078 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3071 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3079 Expect(Token::RPAREN, CHECK_OK); | 3072 Expect(Token::RPAREN, CHECK_OK); |
| 3080 | 3073 |
| 3081 VariableProxy* each = | 3074 VariableProxy* each = |
| 3082 scope_->NewUnresolved(factory(), name, interface); | 3075 scope_->NewUnresolved(factory(), name, interface); |
| 3083 Statement* body = ParseStatement(NULL, CHECK_OK); | 3076 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 3084 InitializeForEachStatement(loop, each, enumerable, body); | 3077 InitializeForEachStatement(loop, each, enumerable, body); |
| 3085 Block* result = | 3078 Block* result = |
| 3086 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3079 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3087 result->AddStatement(variable_statement, zone()); | 3080 result->AddStatement(variable_statement, zone()); |
| 3088 result->AddStatement(loop, zone()); | 3081 result->AddStatement(loop, zone()); |
| 3089 scope_ = saved_scope; | 3082 scope_ = saved_scope; |
| 3090 for_scope->set_end_position(scanner()->location().end_pos); | 3083 for_scope->set_end_position(scanner()->location().end_pos); |
| 3091 for_scope = for_scope->FinalizeBlockScope(); | 3084 for_scope = for_scope->FinalizeBlockScope(); |
| 3092 ASSERT(for_scope == NULL); | 3085 ASSERT(for_scope == NULL); |
| 3093 // Parsed for-in loop w/ variable/const declaration. | 3086 // Parsed for-in loop w/ variable/const declaration. |
| 3094 return result; | 3087 return result; |
| 3095 } else { | 3088 } else { |
| 3096 init = variable_statement; | 3089 init = variable_statement; |
| 3097 } | 3090 } |
| 3098 } else if (peek() == Token::LET) { | 3091 } else if (peek() == Token::LET) { |
| 3099 const AstString* name = NULL; | 3092 Handle<String> name; |
| 3100 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3093 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3101 Block* variable_statement = | 3094 Block* variable_statement = |
| 3102 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3095 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3103 &name, CHECK_OK); | 3096 &name, CHECK_OK); |
| 3104 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3097 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
| 3105 bool accept_OF = decl_props == kHasNoInitializers; | 3098 bool accept_OF = decl_props == kHasNoInitializers; |
| 3106 ForEachStatement::VisitMode mode; | 3099 ForEachStatement::VisitMode mode; |
| 3107 | 3100 |
| 3108 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3101 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
| 3109 // Rewrite a for-in statement of the form | 3102 // Rewrite a for-in statement of the form |
| 3110 // | 3103 // |
| 3111 // for (let x in e) b | 3104 // for (let x in e) b |
| 3112 // | 3105 // |
| 3113 // into | 3106 // into |
| 3114 // | 3107 // |
| 3115 // <let x' be a temporary variable> | 3108 // <let x' be a temporary variable> |
| 3116 // for (x' in e) { | 3109 // for (x' in e) { |
| 3117 // let x; | 3110 // let x; |
| 3118 // x = x'; | 3111 // x = x'; |
| 3119 // b; | 3112 // b; |
| 3120 // } | 3113 // } |
| 3121 | 3114 |
| 3122 // TODO(keuchel): Move the temporary variable to the block scope, after | 3115 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 3123 // implementing stack allocated block scoped variables. | 3116 // implementing stack allocated block scoped variables. |
| 3124 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3117 Factory* heap_factory = isolate()->factory(); |
| 3125 ast_value_factory_->dot_for_string()); | 3118 Handle<String> tempstr; |
| 3119 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3120 isolate(), tempstr, |
| 3121 heap_factory->NewConsString(heap_factory->dot_for_string(), name), |
| 3122 0); |
| 3123 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
| 3124 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); |
| 3126 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3125 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 3127 ForEachStatement* loop = | 3126 ForEachStatement* loop = |
| 3128 factory()->NewForEachStatement(mode, labels, pos); | 3127 factory()->NewForEachStatement(mode, labels, pos); |
| 3129 Target target(&this->target_stack_, loop); | 3128 Target target(&this->target_stack_, loop); |
| 3130 | 3129 |
| 3131 // The expression does not see the loop variable. | 3130 // The expression does not see the loop variable. |
| 3132 scope_ = saved_scope; | 3131 scope_ = saved_scope; |
| 3133 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3132 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3134 scope_ = for_scope; | 3133 scope_ = for_scope; |
| 3135 Expect(Token::RPAREN, CHECK_OK); | 3134 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3246 // DebuggerStatement :: | 3245 // DebuggerStatement :: |
| 3247 // 'debugger' ';' | 3246 // 'debugger' ';' |
| 3248 | 3247 |
| 3249 int pos = peek_position(); | 3248 int pos = peek_position(); |
| 3250 Expect(Token::DEBUGGER, CHECK_OK); | 3249 Expect(Token::DEBUGGER, CHECK_OK); |
| 3251 ExpectSemicolon(CHECK_OK); | 3250 ExpectSemicolon(CHECK_OK); |
| 3252 return factory()->NewDebuggerStatement(pos); | 3251 return factory()->NewDebuggerStatement(pos); |
| 3253 } | 3252 } |
| 3254 | 3253 |
| 3255 | 3254 |
| 3256 void Parser::ReportInvalidCachedData(const AstString* name, bool* ok) { | 3255 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { |
| 3257 ParserTraits::ReportMessage("invalid_cached_data_function", name); | 3256 ParserTraits::ReportMessage("invalid_cached_data_function", name); |
| 3258 *ok = false; | 3257 *ok = false; |
| 3259 } | 3258 } |
| 3260 | 3259 |
| 3261 | 3260 |
| 3262 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3261 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3263 if (expression->IsLiteral()) return true; | 3262 if (expression->IsLiteral()) return true; |
| 3264 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3263 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3265 return lit != NULL && lit->is_simple(); | 3264 return lit != NULL && lit->is_simple(); |
| 3266 } | 3265 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3296 return static_cast<LiteralType>(literal_type->value()); | 3295 return static_cast<LiteralType>(literal_type->value()); |
| 3297 } | 3296 } |
| 3298 | 3297 |
| 3299 | 3298 |
| 3300 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3299 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| 3301 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3300 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
| 3302 } | 3301 } |
| 3303 | 3302 |
| 3304 | 3303 |
| 3305 FunctionLiteral* Parser::ParseFunctionLiteral( | 3304 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3306 const AstString* function_name, | 3305 Handle<String> function_name, |
| 3307 Scanner::Location function_name_location, | 3306 Scanner::Location function_name_location, |
| 3308 bool name_is_strict_reserved, | 3307 bool name_is_strict_reserved, |
| 3309 bool is_generator, | 3308 bool is_generator, |
| 3310 int function_token_pos, | 3309 int function_token_pos, |
| 3311 FunctionLiteral::FunctionType function_type, | 3310 FunctionLiteral::FunctionType function_type, |
| 3312 FunctionLiteral::ArityRestriction arity_restriction, | 3311 FunctionLiteral::ArityRestriction arity_restriction, |
| 3313 bool* ok) { | 3312 bool* ok) { |
| 3314 // Function :: | 3313 // Function :: |
| 3315 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3314 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3316 // | 3315 // |
| 3317 // Getter :: | 3316 // Getter :: |
| 3318 // '(' ')' '{' FunctionBody '}' | 3317 // '(' ')' '{' FunctionBody '}' |
| 3319 // | 3318 // |
| 3320 // Setter :: | 3319 // Setter :: |
| 3321 // '(' PropertySetParameterList ')' '{' FunctionBody '}' | 3320 // '(' PropertySetParameterList ')' '{' FunctionBody '}' |
| 3322 | 3321 |
| 3323 int pos = function_token_pos == RelocInfo::kNoPosition | 3322 int pos = function_token_pos == RelocInfo::kNoPosition |
| 3324 ? peek_position() : function_token_pos; | 3323 ? peek_position() : function_token_pos; |
| 3325 | 3324 |
| 3326 // Anonymous functions were passed either the empty symbol or a null | 3325 // Anonymous functions were passed either the empty symbol or a null |
| 3327 // handle as the function name. Remember if we were passed a non-empty | 3326 // handle as the function name. Remember if we were passed a non-empty |
| 3328 // handle to decide whether to invoke function name inference. | 3327 // handle to decide whether to invoke function name inference. |
| 3329 bool should_infer_name = function_name == NULL; | 3328 bool should_infer_name = function_name.is_null(); |
| 3330 | 3329 |
| 3331 // We want a non-null handle as the function name. | 3330 // We want a non-null handle as the function name. |
| 3332 if (should_infer_name) { | 3331 if (should_infer_name) { |
| 3333 function_name = ast_value_factory_->empty_string(); | 3332 function_name = isolate()->factory()->empty_string(); |
| 3334 } | 3333 } |
| 3335 | 3334 |
| 3336 int num_parameters = 0; | 3335 int num_parameters = 0; |
| 3337 // Function declarations are function scoped in normal mode, so they are | 3336 // Function declarations are function scoped in normal mode, so they are |
| 3338 // hoisted. In harmony block scoping mode they are block scoped, so they | 3337 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3339 // are not hoisted. | 3338 // are not hoisted. |
| 3340 // | 3339 // |
| 3341 // One tricky case are function declarations in a local sloppy-mode eval: | 3340 // One tricky case are function declarations in a local sloppy-mode eval: |
| 3342 // their declaration is hoisted, but they still see the local scope. E.g., | 3341 // their declaration is hoisted, but they still see the local scope. E.g., |
| 3343 // | 3342 // |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3375 int expected_property_count = -1; | 3374 int expected_property_count = -1; |
| 3376 int handler_count = 0; | 3375 int handler_count = 0; |
| 3377 FunctionLiteral::ParameterFlag duplicate_parameters = | 3376 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3378 FunctionLiteral::kNoDuplicateParameters; | 3377 FunctionLiteral::kNoDuplicateParameters; |
| 3379 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 3378 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 3380 ? FunctionLiteral::kIsParenthesized | 3379 ? FunctionLiteral::kIsParenthesized |
| 3381 : FunctionLiteral::kNotParenthesized; | 3380 : FunctionLiteral::kNotParenthesized; |
| 3382 AstProperties ast_properties; | 3381 AstProperties ast_properties; |
| 3383 BailoutReason dont_optimize_reason = kNoReason; | 3382 BailoutReason dont_optimize_reason = kNoReason; |
| 3384 // Parse function body. | 3383 // Parse function body. |
| 3385 { | 3384 { FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 3386 FunctionState function_state(&function_state_, &scope_, scope, zone(), | |
| 3387 ast_value_factory_); | |
| 3388 scope_->SetScopeName(function_name); | 3385 scope_->SetScopeName(function_name); |
| 3389 | 3386 |
| 3390 if (is_generator) { | 3387 if (is_generator) { |
| 3391 // For generators, allocating variables in contexts is currently a win | 3388 // For generators, allocating variables in contexts is currently a win |
| 3392 // because it minimizes the work needed to suspend and resume an | 3389 // because it minimizes the work needed to suspend and resume an |
| 3393 // activation. | 3390 // activation. |
| 3394 scope_->ForceContextAllocation(); | 3391 scope_->ForceContextAllocation(); |
| 3395 | 3392 |
| 3396 // Calling a generator returns a generator object. That object is stored | 3393 // Calling a generator returns a generator object. That object is stored |
| 3397 // in a temporary variable, a definition that is used by "yield" | 3394 // in a temporary variable, a definition that is used by "yield" |
| 3398 // expressions. This also marks the FunctionState as a generator. | 3395 // expressions. This also marks the FunctionState as a generator. |
| 3399 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3396 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 3400 ast_value_factory_->dot_generator_object_string()); | 3397 isolate()->factory()->dot_generator_object_string()); |
| 3401 function_state.set_generator_object_variable(temp); | 3398 function_state.set_generator_object_variable(temp); |
| 3402 } | 3399 } |
| 3403 | 3400 |
| 3404 // FormalParameterList :: | 3401 // FormalParameterList :: |
| 3405 // '(' (Identifier)*[','] ')' | 3402 // '(' (Identifier)*[','] ')' |
| 3406 Expect(Token::LPAREN, CHECK_OK); | 3403 Expect(Token::LPAREN, CHECK_OK); |
| 3407 scope->set_start_position(scanner()->location().beg_pos); | 3404 scope->set_start_position(scanner()->location().beg_pos); |
| 3408 | 3405 |
| 3409 // We don't yet know if the function will be strict, so we cannot yet | 3406 // We don't yet know if the function will be strict, so we cannot yet |
| 3410 // produce errors for parameter names or duplicates. However, we remember | 3407 // produce errors for parameter names or duplicates. However, we remember |
| 3411 // the locations of these errors if they occur and produce the errors later. | 3408 // the locations of these errors if they occur and produce the errors later. |
| 3412 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3409 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 3413 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3410 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 3414 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3411 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3415 | 3412 |
| 3416 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || | 3413 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 3417 (peek() == Token::RPAREN && | 3414 (peek() == Token::RPAREN && |
| 3418 arity_restriction != FunctionLiteral::SETTER_ARITY); | 3415 arity_restriction != FunctionLiteral::SETTER_ARITY); |
| 3419 while (!done) { | 3416 while (!done) { |
| 3420 bool is_strict_reserved = false; | 3417 bool is_strict_reserved = false; |
| 3421 const AstString* param_name = | 3418 Handle<String> param_name = |
| 3422 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3419 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3423 | 3420 |
| 3424 // Store locations for possible future error reports. | 3421 // Store locations for possible future error reports. |
| 3425 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3422 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 3426 eval_args_error_log = scanner()->location(); | 3423 eval_args_error_log = scanner()->location(); |
| 3427 } | 3424 } |
| 3428 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3425 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3429 reserved_loc = scanner()->location(); | 3426 reserved_loc = scanner()->location(); |
| 3430 } | 3427 } |
| 3431 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3428 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3456 // instead of Variables and Proxis as is the case now. | 3453 // instead of Variables and Proxis as is the case now. |
| 3457 Variable* fvar = NULL; | 3454 Variable* fvar = NULL; |
| 3458 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3455 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3459 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3456 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3460 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3457 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3461 fvar_init_op = Token::INIT_CONST; | 3458 fvar_init_op = Token::INIT_CONST; |
| 3462 } | 3459 } |
| 3463 VariableMode fvar_mode = | 3460 VariableMode fvar_mode = |
| 3464 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3461 allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
| 3465 : CONST_LEGACY; | 3462 : CONST_LEGACY; |
| 3466 ASSERT(function_name != NULL); | |
| 3467 fvar = new(zone()) Variable(scope_, | 3463 fvar = new(zone()) Variable(scope_, |
| 3468 function_name, fvar_mode, true /* is valid LHS */, | 3464 function_name, fvar_mode, true /* is valid LHS */, |
| 3469 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3465 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3470 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3466 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3471 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3467 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3472 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3468 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3473 scope_->DeclareFunctionVar(fvar_declaration); | 3469 scope_->DeclareFunctionVar(fvar_declaration); |
| 3474 } | 3470 } |
| 3475 | 3471 |
| 3476 // Determine if the function can be parsed lazily. Lazy parsing is different | 3472 // 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... |
| 3560 | 3556 |
| 3561 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3557 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| 3562 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3558 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3563 } | 3559 } |
| 3564 | 3560 |
| 3565 FunctionLiteral::IsGeneratorFlag generator = is_generator | 3561 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 3566 ? FunctionLiteral::kIsGenerator | 3562 ? FunctionLiteral::kIsGenerator |
| 3567 : FunctionLiteral::kNotGenerator; | 3563 : FunctionLiteral::kNotGenerator; |
| 3568 FunctionLiteral* function_literal = | 3564 FunctionLiteral* function_literal = |
| 3569 factory()->NewFunctionLiteral(function_name, | 3565 factory()->NewFunctionLiteral(function_name, |
| 3570 ast_value_factory_, | |
| 3571 scope, | 3566 scope, |
| 3572 body, | 3567 body, |
| 3573 materialized_literal_count, | 3568 materialized_literal_count, |
| 3574 expected_property_count, | 3569 expected_property_count, |
| 3575 handler_count, | 3570 handler_count, |
| 3576 num_parameters, | 3571 num_parameters, |
| 3577 duplicate_parameters, | 3572 duplicate_parameters, |
| 3578 function_type, | 3573 function_type, |
| 3579 FunctionLiteral::kIsFunction, | 3574 FunctionLiteral::kIsFunction, |
| 3580 parenthesized, | 3575 parenthesized, |
| 3581 generator, | 3576 generator, |
| 3582 pos); | 3577 pos); |
| 3583 function_literal->set_function_token_position(function_token_pos); | 3578 function_literal->set_function_token_position(function_token_pos); |
| 3584 function_literal->set_ast_properties(&ast_properties); | 3579 function_literal->set_ast_properties(&ast_properties); |
| 3585 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3580 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 3586 | 3581 |
| 3587 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3582 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3588 return function_literal; | 3583 return function_literal; |
| 3589 } | 3584 } |
| 3590 | 3585 |
| 3591 | 3586 |
| 3592 void Parser::SkipLazyFunctionBody(const AstString* function_name, | 3587 void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
| 3593 int* materialized_literal_count, | 3588 int* materialized_literal_count, |
| 3594 int* expected_property_count, | 3589 int* expected_property_count, |
| 3595 bool* ok) { | 3590 bool* ok) { |
| 3596 int function_block_pos = position(); | 3591 int function_block_pos = position(); |
| 3597 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3592 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 3598 // If we have cached data, we use it to skip parsing the function body. The | 3593 // If we have cached data, we use it to skip parsing the function body. The |
| 3599 // data contains the information we need to construct the lazy function. | 3594 // data contains the information we need to construct the lazy function. |
| 3600 FunctionEntry entry = | 3595 FunctionEntry entry = |
| 3601 (*cached_data())->GetFunctionEntry(function_block_pos); | 3596 (*cached_data())->GetFunctionEntry(function_block_pos); |
| 3602 if (entry.is_valid()) { | 3597 if (entry.is_valid()) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3661 log_->LogFunction(function_block_pos, body_end, | 3656 log_->LogFunction(function_block_pos, body_end, |
| 3662 *materialized_literal_count, | 3657 *materialized_literal_count, |
| 3663 *expected_property_count, | 3658 *expected_property_count, |
| 3664 scope_->strict_mode()); | 3659 scope_->strict_mode()); |
| 3665 } | 3660 } |
| 3666 } | 3661 } |
| 3667 } | 3662 } |
| 3668 | 3663 |
| 3669 | 3664 |
| 3670 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3665 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3671 const AstString* function_name, int pos, Variable* fvar, | 3666 Handle<String> function_name, int pos, Variable* fvar, |
| 3672 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3667 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3673 // Everything inside an eagerly parsed function will be parsed eagerly | 3668 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3674 // (see comment above). | 3669 // (see comment above). |
| 3675 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3670 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 3676 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3671 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3677 if (fvar != NULL) { | 3672 if (fvar != NULL) { |
| 3678 VariableProxy* fproxy = scope_->NewUnresolved( | 3673 VariableProxy* fproxy = scope_->NewUnresolved( |
| 3679 factory(), function_name, Interface::NewConst()); | 3674 factory(), function_name, Interface::NewConst()); |
| 3680 fproxy->BindTo(fvar); | 3675 fproxy->BindTo(fvar); |
| 3681 body->Add(factory()->NewExpressionStatement( | 3676 body->Add(factory()->NewExpressionStatement( |
| 3682 factory()->NewAssignment(fvar_init_op, | 3677 factory()->NewAssignment(fvar_init_op, |
| 3683 fproxy, | 3678 fproxy, |
| 3684 factory()->NewThisFunction(pos), | 3679 factory()->NewThisFunction(pos), |
| 3685 RelocInfo::kNoPosition), | 3680 RelocInfo::kNoPosition), |
| 3686 RelocInfo::kNoPosition), zone()); | 3681 RelocInfo::kNoPosition), zone()); |
| 3687 } | 3682 } |
| 3688 | 3683 |
| 3689 // For generators, allocate and yield an iterator on function entry. | 3684 // For generators, allocate and yield an iterator on function entry. |
| 3690 if (is_generator) { | 3685 if (is_generator) { |
| 3691 ZoneList<Expression*>* arguments = | 3686 ZoneList<Expression*>* arguments = |
| 3692 new(zone()) ZoneList<Expression*>(0, zone()); | 3687 new(zone()) ZoneList<Expression*>(0, zone()); |
| 3693 CallRuntime* allocation = factory()->NewCallRuntime( | 3688 CallRuntime* allocation = factory()->NewCallRuntime( |
| 3694 ast_value_factory_->empty_string(), | 3689 isolate()->factory()->empty_string(), |
| 3695 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), | 3690 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
| 3696 arguments, pos); | 3691 arguments, pos); |
| 3697 VariableProxy* init_proxy = factory()->NewVariableProxy( | 3692 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 3698 function_state_->generator_object_variable()); | 3693 function_state_->generator_object_variable()); |
| 3699 Assignment* assignment = factory()->NewAssignment( | 3694 Assignment* assignment = factory()->NewAssignment( |
| 3700 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3695 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 3701 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3696 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3702 function_state_->generator_object_variable()); | 3697 function_state_->generator_object_variable()); |
| 3703 Yield* yield = factory()->NewYield( | 3698 Yield* yield = factory()->NewYield( |
| 3704 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 3699 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 3705 body->Add(factory()->NewExpressionStatement( | 3700 body->Add(factory()->NewExpressionStatement( |
| 3706 yield, RelocInfo::kNoPosition), zone()); | 3701 yield, RelocInfo::kNoPosition), zone()); |
| 3707 } | 3702 } |
| 3708 | 3703 |
| 3709 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 3704 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 3710 | 3705 |
| 3711 if (is_generator) { | 3706 if (is_generator) { |
| 3712 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3707 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 3713 function_state_->generator_object_variable()); | 3708 function_state_->generator_object_variable()); |
| 3714 Expression* undefined = | 3709 Expression *undefined = factory()->NewLiteral( |
| 3715 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 3710 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| 3716 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL, | 3711 Yield* yield = factory()->NewYield( |
| 3717 RelocInfo::kNoPosition); | 3712 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| 3718 body->Add(factory()->NewExpressionStatement( | 3713 body->Add(factory()->NewExpressionStatement( |
| 3719 yield, RelocInfo::kNoPosition), zone()); | 3714 yield, RelocInfo::kNoPosition), zone()); |
| 3720 } | 3715 } |
| 3721 | 3716 |
| 3722 Expect(Token::RBRACE, CHECK_OK); | 3717 Expect(Token::RBRACE, CHECK_OK); |
| 3723 scope_->set_end_position(scanner()->location().end_pos); | 3718 scope_->set_end_position(scanner()->location().end_pos); |
| 3724 | 3719 |
| 3725 return body; | 3720 return body; |
| 3726 } | 3721 } |
| 3727 | 3722 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3751 } | 3746 } |
| 3752 | 3747 |
| 3753 | 3748 |
| 3754 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3749 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3755 // CallRuntime :: | 3750 // CallRuntime :: |
| 3756 // '%' Identifier Arguments | 3751 // '%' Identifier Arguments |
| 3757 | 3752 |
| 3758 int pos = peek_position(); | 3753 int pos = peek_position(); |
| 3759 Expect(Token::MOD, CHECK_OK); | 3754 Expect(Token::MOD, CHECK_OK); |
| 3760 // Allow "eval" or "arguments" for backward compatibility. | 3755 // Allow "eval" or "arguments" for backward compatibility. |
| 3761 const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3756 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3762 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3757 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3763 | 3758 |
| 3764 if (extension_ != NULL) { | 3759 if (extension_ != NULL) { |
| 3765 // The extension structures are only accessible while parsing the | 3760 // The extension structures are only accessible while parsing the |
| 3766 // very first time not when reparsing because of lazy compilation. | 3761 // very first time not when reparsing because of lazy compilation. |
| 3767 scope_->DeclarationScope()->ForceEagerCompilation(); | 3762 scope_->DeclarationScope()->ForceEagerCompilation(); |
| 3768 } | 3763 } |
| 3769 | 3764 |
| 3770 const Runtime::Function* function = Runtime::FunctionForName(name->string()); | 3765 const Runtime::Function* function = Runtime::FunctionForName(name); |
| 3771 | 3766 |
| 3772 // Check for built-in IS_VAR macro. | 3767 // Check for built-in IS_VAR macro. |
| 3773 if (function != NULL && | 3768 if (function != NULL && |
| 3774 function->intrinsic_type == Runtime::RUNTIME && | 3769 function->intrinsic_type == Runtime::RUNTIME && |
| 3775 function->function_id == Runtime::kIS_VAR) { | 3770 function->function_id == Runtime::kIS_VAR) { |
| 3776 // %IS_VAR(x) evaluates to x if x is a variable, | 3771 // %IS_VAR(x) evaluates to x if x is a variable, |
| 3777 // leads to a parse error otherwise. Could be implemented as an | 3772 // leads to a parse error otherwise. Could be implemented as an |
| 3778 // inline function %_IS_VAR(x) to eliminate this special case. | 3773 // inline function %_IS_VAR(x) to eliminate this special case. |
| 3779 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { | 3774 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
| 3780 return args->at(0); | 3775 return args->at(0); |
| 3781 } else { | 3776 } else { |
| 3782 ReportMessage("not_isvar"); | 3777 ReportMessage("not_isvar"); |
| 3783 *ok = false; | 3778 *ok = false; |
| 3784 return NULL; | 3779 return NULL; |
| 3785 } | 3780 } |
| 3786 } | 3781 } |
| 3787 | 3782 |
| 3788 // Check that the expected number of arguments are being passed. | 3783 // Check that the expected number of arguments are being passed. |
| 3789 if (function != NULL && | 3784 if (function != NULL && |
| 3790 function->nargs != -1 && | 3785 function->nargs != -1 && |
| 3791 function->nargs != args->length()) { | 3786 function->nargs != args->length()) { |
| 3792 ReportMessage("illegal_access"); | 3787 ReportMessage("illegal_access"); |
| 3793 *ok = false; | 3788 *ok = false; |
| 3794 return NULL; | 3789 return NULL; |
| 3795 } | 3790 } |
| 3796 | 3791 |
| 3797 // Check that the function is defined if it's an inline runtime call. | 3792 // Check that the function is defined if it's an inline runtime call. |
| 3798 if (function == NULL && name->FirstCharacter() == '_') { | 3793 if (function == NULL && name->Get(0) == '_') { |
| 3799 ParserTraits::ReportMessage("not_defined", name); | 3794 ParserTraits::ReportMessage("not_defined", name); |
| 3800 *ok = false; | 3795 *ok = false; |
| 3801 return NULL; | 3796 return NULL; |
| 3802 } | 3797 } |
| 3803 | 3798 |
| 3804 // We have a valid intrinsics call or a call to a builtin. | 3799 // We have a valid intrinsics call or a call to a builtin. |
| 3805 return factory()->NewCallRuntime(name, function, args, pos); | 3800 return factory()->NewCallRuntime(name, function, args, pos); |
| 3806 } | 3801 } |
| 3807 | 3802 |
| 3808 | 3803 |
| 3809 Literal* Parser::GetLiteralUndefined(int position) { | 3804 Literal* Parser::GetLiteralUndefined(int position) { |
| 3810 return factory()->NewUndefinedLiteral(position); | 3805 return factory()->NewLiteral( |
| 3806 isolate()->factory()->undefined_value(), position); |
| 3811 } | 3807 } |
| 3812 | 3808 |
| 3813 | 3809 |
| 3814 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3810 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 3815 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3811 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 3816 if (decl != NULL) { | 3812 if (decl != NULL) { |
| 3817 // In harmony mode we treat conflicting variable bindinds as early | 3813 // In harmony mode we treat conflicting variable bindinds as early |
| 3818 // errors. See ES5 16 for a definition of early errors. | 3814 // errors. See ES5 16 for a definition of early errors. |
| 3819 const AstString* name = decl->proxy()->raw_name(); | 3815 Handle<String> name = decl->proxy()->name(); |
| 3820 int position = decl->proxy()->position(); | 3816 int position = decl->proxy()->position(); |
| 3821 Scanner::Location location = position == RelocInfo::kNoPosition | 3817 Scanner::Location location = position == RelocInfo::kNoPosition |
| 3822 ? Scanner::Location::invalid() | 3818 ? Scanner::Location::invalid() |
| 3823 : Scanner::Location(position, position + 1); | 3819 : Scanner::Location(position, position + 1); |
| 3824 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 3820 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
| 3825 *ok = false; | 3821 *ok = false; |
| 3826 } | 3822 } |
| 3827 } | 3823 } |
| 3828 | 3824 |
| 3829 | 3825 |
| 3830 // ---------------------------------------------------------------------------- | 3826 // ---------------------------------------------------------------------------- |
| 3831 // Parser support | 3827 // Parser support |
| 3832 | 3828 |
| 3833 | 3829 |
| 3834 bool Parser::TargetStackContainsLabel(const AstString* label) { | 3830 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| 3835 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3831 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3836 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3832 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3837 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 3833 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 3838 return true; | 3834 return true; |
| 3839 } | 3835 } |
| 3840 return false; | 3836 return false; |
| 3841 } | 3837 } |
| 3842 | 3838 |
| 3843 | 3839 |
| 3844 BreakableStatement* Parser::LookupBreakTarget(const AstString* label, | 3840 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
| 3845 bool* ok) { | 3841 bool anonymous = label.is_null(); |
| 3846 bool anonymous = label == NULL; | |
| 3847 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3842 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3848 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3843 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 3849 if (stat == NULL) continue; | 3844 if (stat == NULL) continue; |
| 3850 if ((anonymous && stat->is_target_for_anonymous()) || | 3845 if ((anonymous && stat->is_target_for_anonymous()) || |
| 3851 (!anonymous && ContainsLabel(stat->labels(), label))) { | 3846 (!anonymous && ContainsLabel(stat->labels(), label))) { |
| 3852 RegisterTargetUse(stat->break_target(), t->previous()); | 3847 RegisterTargetUse(stat->break_target(), t->previous()); |
| 3853 return stat; | 3848 return stat; |
| 3854 } | 3849 } |
| 3855 } | 3850 } |
| 3856 return NULL; | 3851 return NULL; |
| 3857 } | 3852 } |
| 3858 | 3853 |
| 3859 | 3854 |
| 3860 IterationStatement* Parser::LookupContinueTarget(const AstString* label, | 3855 IterationStatement* Parser::LookupContinueTarget(Handle<String> label, |
| 3861 bool* ok) { | 3856 bool* ok) { |
| 3862 bool anonymous = label == NULL; | 3857 bool anonymous = label.is_null(); |
| 3863 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3858 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3864 IterationStatement* stat = t->node()->AsIterationStatement(); | 3859 IterationStatement* stat = t->node()->AsIterationStatement(); |
| 3865 if (stat == NULL) continue; | 3860 if (stat == NULL) continue; |
| 3866 | 3861 |
| 3867 ASSERT(stat->is_target_for_anonymous()); | 3862 ASSERT(stat->is_target_for_anonymous()); |
| 3868 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3863 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 3869 RegisterTargetUse(stat->continue_target(), t->previous()); | 3864 RegisterTargetUse(stat->continue_target(), t->previous()); |
| 3870 return stat; | 3865 return stat; |
| 3871 } | 3866 } |
| 3872 } | 3867 } |
| 3873 return NULL; | 3868 return NULL; |
| 3874 } | 3869 } |
| 3875 | 3870 |
| 3876 | 3871 |
| 3877 void Parser::RegisterTargetUse(Label* target, Target* stop) { | 3872 void Parser::RegisterTargetUse(Label* target, Target* stop) { |
| 3878 // Register that a break target found at the given stop in the | 3873 // Register that a break target found at the given stop in the |
| 3879 // target stack has been used from the top of the target stack. Add | 3874 // target stack has been used from the top of the target stack. Add |
| 3880 // the break target to any TargetCollectors passed on the stack. | 3875 // the break target to any TargetCollectors passed on the stack. |
| 3881 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3876 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
| 3882 TargetCollector* collector = t->node()->AsTargetCollector(); | 3877 TargetCollector* collector = t->node()->AsTargetCollector(); |
| 3883 if (collector != NULL) collector->AddTarget(target, zone()); | 3878 if (collector != NULL) collector->AddTarget(target, zone()); |
| 3884 } | 3879 } |
| 3885 } | 3880 } |
| 3886 | 3881 |
| 3887 | 3882 |
| 3888 void Parser::ThrowPendingError() { | 3883 void Parser::ThrowPendingError() { |
| 3889 ASSERT(ast_value_factory_->IsInternalized()); | |
| 3890 if (has_pending_error_) { | 3884 if (has_pending_error_) { |
| 3891 MessageLocation location(script_, | 3885 MessageLocation location(script_, |
| 3892 pending_error_location_.beg_pos, | 3886 pending_error_location_.beg_pos, |
| 3893 pending_error_location_.end_pos); | 3887 pending_error_location_.end_pos); |
| 3894 Factory* factory = isolate()->factory(); | 3888 Factory* factory = isolate()->factory(); |
| 3895 bool has_arg = | 3889 bool has_arg = |
| 3896 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | 3890 !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL; |
| 3897 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 3891 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
| 3898 if (pending_error_arg_ != NULL) { | 3892 if (!pending_error_arg_.is_null()) { |
| 3899 Handle<String> arg_string = pending_error_arg_->string(); | 3893 elements->set(0, *(pending_error_arg_.ToHandleChecked())); |
| 3900 elements->set(0, *arg_string); | |
| 3901 } else if (pending_error_char_arg_ != NULL) { | 3894 } else if (pending_error_char_arg_ != NULL) { |
| 3902 Handle<String> arg_string = | 3895 Handle<String> arg_string = |
| 3903 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 3896 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
| 3904 .ToHandleChecked(); | 3897 .ToHandleChecked(); |
| 3905 elements->set(0, *arg_string); | 3898 elements->set(0, *arg_string); |
| 3906 } | 3899 } |
| 3907 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 3900 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 3908 Handle<Object> result = pending_error_is_reference_error_ | 3901 Handle<Object> result = pending_error_is_reference_error_ |
| 3909 ? factory->NewReferenceError(pending_error_message_, array) | 3902 ? factory->NewReferenceError(pending_error_message_, array) |
| 3910 : factory->NewSyntaxError(pending_error_message_, array); | 3903 : factory->NewSyntaxError(pending_error_message_, array); |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4804 result->contains_anchor = parser.contains_anchor(); | 4797 result->contains_anchor = parser.contains_anchor(); |
| 4805 result->capture_count = capture_count; | 4798 result->capture_count = capture_count; |
| 4806 } | 4799 } |
| 4807 return !parser.failed(); | 4800 return !parser.failed(); |
| 4808 } | 4801 } |
| 4809 | 4802 |
| 4810 | 4803 |
| 4811 bool Parser::Parse() { | 4804 bool Parser::Parse() { |
| 4812 ASSERT(info()->function() == NULL); | 4805 ASSERT(info()->function() == NULL); |
| 4813 FunctionLiteral* result = NULL; | 4806 FunctionLiteral* result = NULL; |
| 4814 ast_value_factory_ = info()->ast_value_factory(); | |
| 4815 if (ast_value_factory_ == NULL) { | |
| 4816 ast_value_factory_ = new AstValueFactory(zone()); | |
| 4817 } | |
| 4818 if (allow_natives_syntax() || extension_ != NULL) { | |
| 4819 // If intrinsics are allowed, the Parser cannot operate independent of the | |
| 4820 // V8 heap because of Rumtime. Tell the string table to internalize strings | |
| 4821 // and values right after they're created. | |
| 4822 ast_value_factory_->Internalize(isolate()); | |
| 4823 } | |
| 4824 | |
| 4825 if (info()->is_lazy()) { | 4807 if (info()->is_lazy()) { |
| 4826 ASSERT(!info()->is_eval()); | 4808 ASSERT(!info()->is_eval()); |
| 4827 if (info()->shared_info()->is_function()) { | 4809 if (info()->shared_info()->is_function()) { |
| 4828 result = ParseLazy(); | 4810 result = ParseLazy(); |
| 4829 } else { | 4811 } else { |
| 4830 result = ParseProgram(); | 4812 result = ParseProgram(); |
| 4831 } | 4813 } |
| 4832 } else { | 4814 } else { |
| 4833 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4815 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
| 4834 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && | 4816 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
| 4835 (*info()->cached_data())->has_error()) { | 4817 (*info()->cached_data())->has_error()) { |
| 4836 ScriptData* cached_data = *(info()->cached_data()); | 4818 ScriptData* cached_data = *(info()->cached_data()); |
| 4837 Scanner::Location loc = cached_data->MessageLocation(); | 4819 Scanner::Location loc = cached_data->MessageLocation(); |
| 4838 const char* message = cached_data->BuildMessage(); | 4820 const char* message = cached_data->BuildMessage(); |
| 4839 const char* arg = cached_data->BuildArg(); | 4821 const char* arg = cached_data->BuildArg(); |
| 4840 ParserTraits::ReportMessageAt(loc, message, arg, | 4822 ParserTraits::ReportMessageAt(loc, message, arg, |
| 4841 cached_data->IsReferenceError()); | 4823 cached_data->IsReferenceError()); |
| 4842 DeleteArray(message); | 4824 DeleteArray(message); |
| 4843 DeleteArray(arg); | 4825 DeleteArray(arg); |
| 4844 ASSERT(info()->isolate()->has_pending_exception()); | 4826 ASSERT(info()->isolate()->has_pending_exception()); |
| 4845 } else { | 4827 } else { |
| 4846 result = ParseProgram(); | 4828 result = ParseProgram(); |
| 4847 } | 4829 } |
| 4848 } | 4830 } |
| 4849 info()->SetFunction(result); | 4831 info()->SetFunction(result); |
| 4850 ASSERT(ast_value_factory_->IsInternalized()); | |
| 4851 // info takes ownership of ast_value_factory_. | |
| 4852 if (info()->ast_value_factory() == NULL) { | |
| 4853 info()->SetAstValueFactory(ast_value_factory_); | |
| 4854 } | |
| 4855 ast_value_factory_ = NULL; | |
| 4856 return (result != NULL); | 4832 return (result != NULL); |
| 4857 } | 4833 } |
| 4858 | 4834 |
| 4859 } } // namespace v8::internal | 4835 } } // namespace v8::internal |
| OLD | NEW |