OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 528 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
529 for (int i = 0; i < args.length(); i++) { | 529 for (int i = 0; i < args.length(); i++) { |
530 elements->set(i, *args[i]); | 530 elements->set(i, *args[i]); |
531 } | 531 } |
532 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 532 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
533 Handle<Object> result = factory->NewSyntaxError(message, array); | 533 Handle<Object> result = factory->NewSyntaxError(message, array); |
534 parser_->isolate()->Throw(*result, &location); | 534 parser_->isolate()->Throw(*result, &location); |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 Handle<String> ParserTraits::GetSymbol() { | 538 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
539 int symbol_id = -1; | 539 int symbol_id = -1; |
540 if (parser_->pre_parse_data() != NULL) { | 540 if (parser_->pre_parse_data() != NULL) { |
541 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | 541 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); |
542 } | 542 } |
543 return parser_->LookupSymbol(symbol_id); | 543 return parser_->LookupSymbol(symbol_id); |
544 } | 544 } |
545 | 545 |
546 | 546 |
547 Handle<String> ParserTraits::NextLiteralString(PretenureFlag tenured) { | 547 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
548 Scanner& scanner = parser_->scanner(); | 548 PretenureFlag tenured) { |
549 if (scanner.is_next_literal_ascii()) { | 549 if (scanner->is_next_literal_ascii()) { |
550 return parser_->isolate_->factory()->NewStringFromAscii( | 550 return parser_->isolate_->factory()->NewStringFromAscii( |
551 scanner.next_literal_ascii_string(), tenured); | 551 scanner->next_literal_ascii_string(), tenured); |
552 } else { | 552 } else { |
553 return parser_->isolate_->factory()->NewStringFromTwoByte( | 553 return parser_->isolate_->factory()->NewStringFromTwoByte( |
554 scanner.next_literal_utf16_string(), tenured); | 554 scanner->next_literal_utf16_string(), tenured); |
555 } | 555 } |
556 } | 556 } |
557 | 557 |
558 | 558 |
| 559 Expression* ParserTraits::ThisExpression( |
| 560 Scope* scope, |
| 561 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 562 return factory->NewVariableProxy(scope->receiver()); |
| 563 } |
| 564 |
| 565 |
| 566 Expression* ParserTraits::ExpressionFromLiteral( |
| 567 Token::Value token, int pos, |
| 568 Scanner* scanner, |
| 569 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 570 Factory* isolate_factory = parser_->isolate()->factory(); |
| 571 switch (token) { |
| 572 case Token::NULL_LITERAL: |
| 573 return factory->NewLiteral(isolate_factory->null_value(), pos); |
| 574 case Token::TRUE_LITERAL: |
| 575 return factory->NewLiteral(isolate_factory->true_value(), pos); |
| 576 case Token::FALSE_LITERAL: |
| 577 return factory->NewLiteral(isolate_factory->false_value(), pos); |
| 578 case Token::NUMBER: { |
| 579 ASSERT(scanner->is_literal_ascii()); |
| 580 double value = StringToDouble(parser_->isolate()->unicode_cache(), |
| 581 scanner->literal_ascii_string(), |
| 582 ALLOW_HEX | ALLOW_OCTAL | |
| 583 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 584 return factory->NewNumberLiteral(value, pos); |
| 585 } |
| 586 default: |
| 587 ASSERT(false); |
| 588 } |
| 589 return NULL; |
| 590 } |
| 591 |
| 592 |
| 593 Expression* ParserTraits::ExpressionFromIdentifier( |
| 594 Handle<String> name, int pos, Scope* scope, |
| 595 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 596 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 597 // The name may refer to a module instance object, so its type is unknown. |
| 598 #ifdef DEBUG |
| 599 if (FLAG_print_interface_details) |
| 600 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 601 #endif |
| 602 Interface* interface = Interface::NewUnknown(parser_->zone()); |
| 603 return scope->NewUnresolved(factory, name, interface, pos); |
| 604 } |
| 605 |
| 606 |
| 607 Expression* ParserTraits::ExpressionFromString( |
| 608 int pos, Scanner* scanner, |
| 609 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 610 Handle<String> symbol = GetSymbol(scanner); |
| 611 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 612 return factory->NewLiteral(symbol, pos); |
| 613 } |
| 614 |
| 615 |
| 616 Expression* ParserTraits::ParseArrayLiteral(bool* ok) { |
| 617 return parser_->ParseArrayLiteral(ok); |
| 618 } |
| 619 |
| 620 |
| 621 Expression* ParserTraits::ParseObjectLiteral(bool* ok) { |
| 622 return parser_->ParseObjectLiteral(ok); |
| 623 } |
| 624 |
| 625 |
| 626 Expression* ParserTraits::ParseExpression(bool accept_IN, bool* ok) { |
| 627 return parser_->ParseExpression(accept_IN, ok); |
| 628 } |
| 629 |
| 630 |
| 631 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 632 return parser_->ParseV8Intrinsic(ok); |
| 633 } |
| 634 |
| 635 |
559 Parser::Parser(CompilationInfo* info) | 636 Parser::Parser(CompilationInfo* info) |
560 : ParserBase<ParserTraits>(&scanner_, | 637 : ParserBase<ParserTraits>(&scanner_, |
561 info->isolate()->stack_guard()->real_climit(), | 638 info->isolate()->stack_guard()->real_climit(), |
| 639 info->extension(), |
562 this), | 640 this), |
563 isolate_(info->isolate()), | 641 isolate_(info->isolate()), |
564 symbol_cache_(0, info->zone()), | 642 symbol_cache_(0, info->zone()), |
565 script_(info->script()), | 643 script_(info->script()), |
566 scanner_(isolate_->unicode_cache()), | 644 scanner_(isolate_->unicode_cache()), |
567 reusable_preparser_(NULL), | 645 reusable_preparser_(NULL), |
568 original_scope_(NULL), | 646 original_scope_(NULL), |
569 target_stack_(NULL), | 647 target_stack_(NULL), |
570 extension_(info->extension()), | |
571 pre_parse_data_(NULL), | 648 pre_parse_data_(NULL), |
572 fni_(NULL), | 649 fni_(NULL), |
573 zone_(info->zone()), | 650 zone_(info->zone()), |
574 info_(info) { | 651 info_(info) { |
575 ASSERT(!script_.is_null()); | 652 ASSERT(!script_.is_null()); |
576 isolate_->set_ast_node_id(0); | 653 isolate_->set_ast_node_id(0); |
577 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 654 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
578 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 655 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
579 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 656 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
580 set_allow_lazy(false); // Must be explicitly enabled. | 657 set_allow_lazy(false); // Must be explicitly enabled. |
(...skipping 2842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3423 | 3500 |
3424 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 3501 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
3425 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 3502 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
3426 const char* element[1] = { name_string.get() }; | 3503 const char* element[1] = { name_string.get() }; |
3427 ReportMessage("invalid_preparser_data", | 3504 ReportMessage("invalid_preparser_data", |
3428 Vector<const char*>(element, 1)); | 3505 Vector<const char*>(element, 1)); |
3429 *ok = false; | 3506 *ok = false; |
3430 } | 3507 } |
3431 | 3508 |
3432 | 3509 |
3433 Expression* Parser::ParsePrimaryExpression(bool* ok) { | |
3434 // PrimaryExpression :: | |
3435 // 'this' | |
3436 // 'null' | |
3437 // 'true' | |
3438 // 'false' | |
3439 // Identifier | |
3440 // Number | |
3441 // String | |
3442 // ArrayLiteral | |
3443 // ObjectLiteral | |
3444 // RegExpLiteral | |
3445 // '(' Expression ')' | |
3446 | |
3447 int pos = peek_position(); | |
3448 Expression* result = NULL; | |
3449 switch (peek()) { | |
3450 case Token::THIS: { | |
3451 Consume(Token::THIS); | |
3452 result = factory()->NewVariableProxy(scope_->receiver()); | |
3453 break; | |
3454 } | |
3455 | |
3456 case Token::NULL_LITERAL: | |
3457 Consume(Token::NULL_LITERAL); | |
3458 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); | |
3459 break; | |
3460 | |
3461 case Token::TRUE_LITERAL: | |
3462 Consume(Token::TRUE_LITERAL); | |
3463 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); | |
3464 break; | |
3465 | |
3466 case Token::FALSE_LITERAL: | |
3467 Consume(Token::FALSE_LITERAL); | |
3468 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); | |
3469 break; | |
3470 | |
3471 case Token::IDENTIFIER: | |
3472 case Token::YIELD: | |
3473 case Token::FUTURE_STRICT_RESERVED_WORD: { | |
3474 // Using eval or arguments in this context is OK even in strict mode. | |
3475 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | |
3476 if (fni_ != NULL) fni_->PushVariableName(name); | |
3477 // The name may refer to a module instance object, so its type is unknown. | |
3478 #ifdef DEBUG | |
3479 if (FLAG_print_interface_details) | |
3480 PrintF("# Variable %s ", name->ToAsciiArray()); | |
3481 #endif | |
3482 Interface* interface = Interface::NewUnknown(zone()); | |
3483 result = scope_->NewUnresolved(factory(), name, interface, pos); | |
3484 break; | |
3485 } | |
3486 | |
3487 case Token::NUMBER: { | |
3488 Consume(Token::NUMBER); | |
3489 ASSERT(scanner().is_literal_ascii()); | |
3490 double value = StringToDouble(isolate()->unicode_cache(), | |
3491 scanner().literal_ascii_string(), | |
3492 ALLOW_HEX | ALLOW_OCTAL | | |
3493 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | |
3494 result = factory()->NewNumberLiteral(value, pos); | |
3495 break; | |
3496 } | |
3497 | |
3498 case Token::STRING: { | |
3499 Consume(Token::STRING); | |
3500 Handle<String> symbol = GetSymbol(); | |
3501 result = factory()->NewLiteral(symbol, pos); | |
3502 if (fni_ != NULL) fni_->PushLiteralName(symbol); | |
3503 break; | |
3504 } | |
3505 | |
3506 case Token::ASSIGN_DIV: | |
3507 result = ParseRegExpLiteral(true, CHECK_OK); | |
3508 break; | |
3509 | |
3510 case Token::DIV: | |
3511 result = ParseRegExpLiteral(false, CHECK_OK); | |
3512 break; | |
3513 | |
3514 case Token::LBRACK: | |
3515 result = ParseArrayLiteral(CHECK_OK); | |
3516 break; | |
3517 | |
3518 case Token::LBRACE: | |
3519 result = ParseObjectLiteral(CHECK_OK); | |
3520 break; | |
3521 | |
3522 case Token::LPAREN: | |
3523 Consume(Token::LPAREN); | |
3524 // Heuristically try to detect immediately called functions before | |
3525 // seeing the call parentheses. | |
3526 parenthesized_function_ = (peek() == Token::FUNCTION); | |
3527 result = ParseExpression(true, CHECK_OK); | |
3528 Expect(Token::RPAREN, CHECK_OK); | |
3529 break; | |
3530 | |
3531 case Token::MOD: | |
3532 if (allow_natives_syntax() || extension_ != NULL) { | |
3533 result = ParseV8Intrinsic(CHECK_OK); | |
3534 break; | |
3535 } | |
3536 // If we're not allowing special syntax we fall-through to the | |
3537 // default case. | |
3538 | |
3539 default: { | |
3540 Token::Value tok = Next(); | |
3541 ReportUnexpectedToken(tok); | |
3542 *ok = false; | |
3543 return NULL; | |
3544 } | |
3545 } | |
3546 | |
3547 return result; | |
3548 } | |
3549 | |
3550 | |
3551 Expression* Parser::ParseArrayLiteral(bool* ok) { | 3510 Expression* Parser::ParseArrayLiteral(bool* ok) { |
3552 // ArrayLiteral :: | 3511 // ArrayLiteral :: |
3553 // '[' Expression? (',' Expression?)* ']' | 3512 // '[' Expression? (',' Expression?)* ']' |
3554 | 3513 |
3555 int pos = peek_position(); | 3514 int pos = peek_position(); |
3556 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); | 3515 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
3557 Expect(Token::LBRACK, CHECK_OK); | 3516 Expect(Token::LBRACK, CHECK_OK); |
3558 while (peek() != Token::RBRACK) { | 3517 while (peek() != Token::RBRACK) { |
3559 Expression* elem; | 3518 Expression* elem; |
3560 if (peek() == Token::COMMA) { | 3519 if (peek() == Token::COMMA) { |
(...skipping 1890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5451 ASSERT(info()->isolate()->has_pending_exception()); | 5410 ASSERT(info()->isolate()->has_pending_exception()); |
5452 } else { | 5411 } else { |
5453 result = ParseProgram(); | 5412 result = ParseProgram(); |
5454 } | 5413 } |
5455 } | 5414 } |
5456 info()->SetFunction(result); | 5415 info()->SetFunction(result); |
5457 return (result != NULL); | 5416 return (result != NULL); |
5458 } | 5417 } |
5459 | 5418 |
5460 } } // namespace v8::internal | 5419 } } // namespace v8::internal |
OLD | NEW |