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