| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 extension_(extension), | 615 extension_(extension), |
| 616 pre_data_(pre_data), | 616 pre_data_(pre_data), |
| 617 fni_(NULL), | 617 fni_(NULL), |
| 618 stack_overflow_(false), | 618 stack_overflow_(false), |
| 619 parenthesized_function_(false) { | 619 parenthesized_function_(false) { |
| 620 AstNode::ResetIds(); | 620 AstNode::ResetIds(); |
| 621 } | 621 } |
| 622 | 622 |
| 623 | 623 |
| 624 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 624 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 625 bool in_global_context) { | 625 bool in_global_context, |
| 626 StrictModeFlag strict_mode) { |
| 626 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 627 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 627 | 628 |
| 628 HistogramTimerScope timer(COUNTERS->parse()); | 629 HistogramTimerScope timer(COUNTERS->parse()); |
| 629 COUNTERS->total_parse_size()->Increment(source->length()); | 630 COUNTERS->total_parse_size()->Increment(source->length()); |
| 630 fni_ = new FuncNameInferrer(); | 631 fni_ = new FuncNameInferrer(); |
| 631 | 632 |
| 632 // Initialize parser state. | 633 // Initialize parser state. |
| 633 source->TryFlatten(); | 634 source->TryFlatten(); |
| 634 if (source->IsExternalTwoByteString()) { | 635 if (source->IsExternalTwoByteString()) { |
| 635 // Notice that the stream is destroyed at the end of the branch block. | 636 // Notice that the stream is destroyed at the end of the branch block. |
| 636 // The last line of the blocks can't be moved outside, even though they're | 637 // The last line of the blocks can't be moved outside, even though they're |
| 637 // identical calls. | 638 // identical calls. |
| 638 ExternalTwoByteStringUC16CharacterStream stream( | 639 ExternalTwoByteStringUC16CharacterStream stream( |
| 639 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 640 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 640 scanner_.Initialize(&stream); | 641 scanner_.Initialize(&stream); |
| 641 return DoParseProgram(source, in_global_context, &zone_scope); | 642 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); |
| 642 } else { | 643 } else { |
| 643 GenericStringUC16CharacterStream stream(source, 0, source->length()); | 644 GenericStringUC16CharacterStream stream(source, 0, source->length()); |
| 644 scanner_.Initialize(&stream); | 645 scanner_.Initialize(&stream); |
| 645 return DoParseProgram(source, in_global_context, &zone_scope); | 646 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); |
| 646 } | 647 } |
| 647 } | 648 } |
| 648 | 649 |
| 649 | 650 |
| 650 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, | 651 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| 651 bool in_global_context, | 652 bool in_global_context, |
| 653 StrictModeFlag strict_mode, |
| 652 ZoneScope* zone_scope) { | 654 ZoneScope* zone_scope) { |
| 653 ASSERT(target_stack_ == NULL); | 655 ASSERT(target_stack_ == NULL); |
| 654 if (pre_data_ != NULL) pre_data_->Initialize(); | 656 if (pre_data_ != NULL) pre_data_->Initialize(); |
| 655 | 657 |
| 656 // Compute the parsing mode. | 658 // Compute the parsing mode. |
| 657 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 659 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 658 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 660 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 659 | 661 |
| 660 Scope::Type type = | 662 Scope::Type type = |
| 661 in_global_context | 663 in_global_context |
| 662 ? Scope::GLOBAL_SCOPE | 664 ? Scope::GLOBAL_SCOPE |
| 663 : Scope::EVAL_SCOPE; | 665 : Scope::EVAL_SCOPE; |
| 664 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 666 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 665 | 667 |
| 666 FunctionLiteral* result = NULL; | 668 FunctionLiteral* result = NULL; |
| 667 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 669 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 668 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 670 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 669 scope); | 671 scope); |
| 670 TemporaryScope temp_scope(&this->temp_scope_); | 672 TemporaryScope temp_scope(&this->temp_scope_); |
| 673 if (strict_mode == kStrictMode) { |
| 674 temp_scope.EnableStrictMode(); |
| 675 } |
| 671 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 676 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 672 bool ok = true; | 677 bool ok = true; |
| 673 int beg_loc = scanner().location().beg_pos; | 678 int beg_loc = scanner().location().beg_pos; |
| 674 ParseSourceElements(body, Token::EOS, &ok); | 679 ParseSourceElements(body, Token::EOS, &ok); |
| 675 if (ok && temp_scope_->StrictMode()) { | 680 if (ok && temp_scope_->StrictMode()) { |
| 676 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 681 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 677 } | 682 } |
| 678 if (ok) { | 683 if (ok) { |
| 679 result = new FunctionLiteral( | 684 result = new FunctionLiteral( |
| 680 no_name, | 685 no_name, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 | 751 |
| 747 { | 752 { |
| 748 // Parse the function literal. | 753 // Parse the function literal. |
| 749 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 754 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 750 Scope* scope = | 755 Scope* scope = |
| 751 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 756 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 752 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 757 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 753 scope); | 758 scope); |
| 754 TemporaryScope temp_scope(&this->temp_scope_); | 759 TemporaryScope temp_scope(&this->temp_scope_); |
| 755 | 760 |
| 761 if (info->strict_mode()) { |
| 762 temp_scope.EnableStrictMode(); |
| 763 } |
| 764 |
| 756 FunctionLiteralType type = | 765 FunctionLiteralType type = |
| 757 info->is_expression() ? EXPRESSION : DECLARATION; | 766 info->is_expression() ? EXPRESSION : DECLARATION; |
| 758 bool ok = true; | 767 bool ok = true; |
| 759 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); | 768 result = ParseFunctionLiteral(name, |
| 769 false, // Strict mode name already checked. |
| 770 RelocInfo::kNoPosition, type, &ok); |
| 760 // Make sure the results agree. | 771 // Make sure the results agree. |
| 761 ASSERT(ok == (result != NULL)); | 772 ASSERT(ok == (result != NULL)); |
| 762 // The only errors should be stack overflows. | |
| 763 ASSERT(ok || stack_overflow_); | |
| 764 } | 773 } |
| 765 | 774 |
| 766 // Make sure the target stack is empty. | 775 // Make sure the target stack is empty. |
| 767 ASSERT(target_stack_ == NULL); | 776 ASSERT(target_stack_ == NULL); |
| 768 | 777 |
| 769 // If there was a stack overflow we have to get rid of AST and it is | 778 // If there was a stack overflow we have to get rid of AST and it is |
| 770 // not safe to do before scope has been deleted. | 779 // not safe to do before scope has been deleted. |
| 771 if (result == NULL) { | 780 if (result == NULL) { |
| 772 isolate()->StackOverflow(); | |
| 773 zone_scope->DeleteOnExit(); | 781 zone_scope->DeleteOnExit(); |
| 782 if (stack_overflow_) isolate()->StackOverflow(); |
| 774 } else { | 783 } else { |
| 775 Handle<String> inferred_name(info->inferred_name()); | 784 Handle<String> inferred_name(info->inferred_name()); |
| 776 result->set_inferred_name(inferred_name); | 785 result->set_inferred_name(inferred_name); |
| 777 } | 786 } |
| 778 return result; | 787 return result; |
| 779 } | 788 } |
| 780 | 789 |
| 781 | 790 |
| 782 Handle<String> Parser::GetSymbol(bool* ok) { | 791 Handle<String> Parser::GetSymbol(bool* ok) { |
| 783 int symbol_id = -1; | 792 int symbol_id = -1; |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 return new ExpressionStatement( | 1448 return new ExpressionStatement( |
| 1440 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); | 1449 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
| 1441 } | 1450 } |
| 1442 | 1451 |
| 1443 | 1452 |
| 1444 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1453 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
| 1445 // FunctionDeclaration :: | 1454 // FunctionDeclaration :: |
| 1446 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1455 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1447 Expect(Token::FUNCTION, CHECK_OK); | 1456 Expect(Token::FUNCTION, CHECK_OK); |
| 1448 int function_token_position = scanner().location().beg_pos; | 1457 int function_token_position = scanner().location().beg_pos; |
| 1449 Handle<String> name = ParseIdentifier(CHECK_OK); | 1458 bool is_reserved = false; |
| 1459 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); |
| 1450 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1460 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1461 is_reserved, |
| 1451 function_token_position, | 1462 function_token_position, |
| 1452 DECLARATION, | 1463 DECLARATION, |
| 1453 CHECK_OK); | 1464 CHECK_OK); |
| 1454 // Even if we're not at the top-level of the global or a function | 1465 // Even if we're not at the top-level of the global or a function |
| 1455 // scope, we treat is as such and introduce the function with it's | 1466 // scope, we treat is as such and introduce the function with it's |
| 1456 // initial value upon entering the corresponding scope. | 1467 // initial value upon entering the corresponding scope. |
| 1457 Declare(name, Variable::VAR, fun, true, CHECK_OK); | 1468 Declare(name, Variable::VAR, fun, true, CHECK_OK); |
| 1458 return EmptyStatement(); | 1469 return EmptyStatement(); |
| 1459 } | 1470 } |
| 1460 | 1471 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 | 1710 |
| 1700 return false; | 1711 return false; |
| 1701 } | 1712 } |
| 1702 | 1713 |
| 1703 | 1714 |
| 1704 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 1715 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| 1705 bool* ok) { | 1716 bool* ok) { |
| 1706 // ExpressionStatement | LabelledStatement :: | 1717 // ExpressionStatement | LabelledStatement :: |
| 1707 // Expression ';' | 1718 // Expression ';' |
| 1708 // Identifier ':' Statement | 1719 // Identifier ':' Statement |
| 1709 bool starts_with_idenfifier = (peek() == Token::IDENTIFIER); | 1720 bool starts_with_idenfifier = peek_any_identifier(); |
| 1710 Expression* expr = ParseExpression(true, CHECK_OK); | 1721 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1711 if (peek() == Token::COLON && starts_with_idenfifier && expr && | 1722 if (peek() == Token::COLON && starts_with_idenfifier && expr && |
| 1712 expr->AsVariableProxy() != NULL && | 1723 expr->AsVariableProxy() != NULL && |
| 1713 !expr->AsVariableProxy()->is_this()) { | 1724 !expr->AsVariableProxy()->is_this()) { |
| 1714 // Expression is a single identifier, and not, e.g., a parenthesized | 1725 // Expression is a single identifier, and not, e.g., a parenthesized |
| 1715 // identifier. | 1726 // identifier. |
| 1716 VariableProxy* var = expr->AsVariableProxy(); | 1727 VariableProxy* var = expr->AsVariableProxy(); |
| 1717 Handle<String> label = var->name(); | 1728 Handle<String> label = var->name(); |
| 1718 // TODO(1240780): We don't check for redeclaration of labels | 1729 // TODO(1240780): We don't check for redeclaration of labels |
| 1719 // during preparsing since keeping track of the set of active | 1730 // during preparsing since keeping track of the set of active |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2295 // Signal a reference error if the expression is an invalid left-hand | 2306 // Signal a reference error if the expression is an invalid left-hand |
| 2296 // side expression. We could report this as a syntax error here but | 2307 // side expression. We could report this as a syntax error here but |
| 2297 // for compatibility with JSC we choose to report the error at | 2308 // for compatibility with JSC we choose to report the error at |
| 2298 // runtime. | 2309 // runtime. |
| 2299 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2310 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2300 Handle<String> type = | 2311 Handle<String> type = |
| 2301 isolate()->factory()->invalid_lhs_in_assignment_symbol(); | 2312 isolate()->factory()->invalid_lhs_in_assignment_symbol(); |
| 2302 expression = NewThrowReferenceError(type); | 2313 expression = NewThrowReferenceError(type); |
| 2303 } | 2314 } |
| 2304 | 2315 |
| 2316 if (temp_scope_->StrictMode()) { |
| 2317 // Assignment to eval or arguments is disallowed in strict mode. |
| 2318 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2319 } |
| 2320 |
| 2305 Token::Value op = Next(); // Get assignment operator. | 2321 Token::Value op = Next(); // Get assignment operator. |
| 2306 int pos = scanner().location().beg_pos; | 2322 int pos = scanner().location().beg_pos; |
| 2307 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2323 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2308 | 2324 |
| 2309 // TODO(1231235): We try to estimate the set of properties set by | 2325 // TODO(1231235): We try to estimate the set of properties set by |
| 2310 // constructors. We define a new property whenever there is an | 2326 // constructors. We define a new property whenever there is an |
| 2311 // assignment to a property of 'this'. We should probably only add | 2327 // assignment to a property of 'this'. We should probably only add |
| 2312 // properties if we haven't seen them before. Otherwise we'll | 2328 // properties if we haven't seen them before. Otherwise we'll |
| 2313 // probably overestimate the number of properties. | 2329 // probably overestimate the number of properties. |
| 2314 Property* property = expression ? expression->AsProperty() : NULL; | 2330 Property* property = expression ? expression->AsProperty() : NULL; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2522 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2538 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2523 // Signal a reference error if the expression is an invalid | 2539 // Signal a reference error if the expression is an invalid |
| 2524 // left-hand side expression. We could report this as a syntax | 2540 // left-hand side expression. We could report this as a syntax |
| 2525 // error here but for compatibility with JSC we choose to report the | 2541 // error here but for compatibility with JSC we choose to report the |
| 2526 // error at runtime. | 2542 // error at runtime. |
| 2527 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2543 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2528 Handle<String> type = | 2544 Handle<String> type = |
| 2529 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); | 2545 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); |
| 2530 expression = NewThrowReferenceError(type); | 2546 expression = NewThrowReferenceError(type); |
| 2531 } | 2547 } |
| 2548 |
| 2549 if (temp_scope_->StrictMode()) { |
| 2550 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2551 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2552 } |
| 2553 |
| 2532 int position = scanner().location().beg_pos; | 2554 int position = scanner().location().beg_pos; |
| 2533 IncrementOperation* increment = new IncrementOperation(op, expression); | 2555 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2534 return new CountOperation(true /* prefix */, increment, position); | 2556 return new CountOperation(true /* prefix */, increment, position); |
| 2535 | 2557 |
| 2536 } else { | 2558 } else { |
| 2537 return ParsePostfixExpression(ok); | 2559 return ParsePostfixExpression(ok); |
| 2538 } | 2560 } |
| 2539 } | 2561 } |
| 2540 | 2562 |
| 2541 | 2563 |
| 2542 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2564 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 2543 // PostfixExpression :: | 2565 // PostfixExpression :: |
| 2544 // LeftHandSideExpression ('++' | '--')? | 2566 // LeftHandSideExpression ('++' | '--')? |
| 2545 | 2567 |
| 2546 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 2568 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2547 if (!scanner().has_line_terminator_before_next() && | 2569 if (!scanner().has_line_terminator_before_next() && |
| 2548 Token::IsCountOp(peek())) { | 2570 Token::IsCountOp(peek())) { |
| 2549 // Signal a reference error if the expression is an invalid | 2571 // Signal a reference error if the expression is an invalid |
| 2550 // left-hand side expression. We could report this as a syntax | 2572 // left-hand side expression. We could report this as a syntax |
| 2551 // error here but for compatibility with JSC we choose to report the | 2573 // error here but for compatibility with JSC we choose to report the |
| 2552 // error at runtime. | 2574 // error at runtime. |
| 2553 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2575 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2554 Handle<String> type = | 2576 Handle<String> type = |
| 2555 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); | 2577 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); |
| 2556 expression = NewThrowReferenceError(type); | 2578 expression = NewThrowReferenceError(type); |
| 2557 } | 2579 } |
| 2580 |
| 2581 if (temp_scope_->StrictMode()) { |
| 2582 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2583 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2584 } |
| 2585 |
| 2558 Token::Value next = Next(); | 2586 Token::Value next = Next(); |
| 2559 int position = scanner().location().beg_pos; | 2587 int position = scanner().location().beg_pos; |
| 2560 IncrementOperation* increment = new IncrementOperation(next, expression); | 2588 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2561 expression = new CountOperation(false /* postfix */, increment, position); | 2589 expression = new CountOperation(false /* postfix */, increment, position); |
| 2562 } | 2590 } |
| 2563 return expression; | 2591 return expression; |
| 2564 } | 2592 } |
| 2565 | 2593 |
| 2566 | 2594 |
| 2567 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 2595 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2677 // MemberExpression :: | 2705 // MemberExpression :: |
| 2678 // (PrimaryExpression | FunctionLiteral) | 2706 // (PrimaryExpression | FunctionLiteral) |
| 2679 // ('[' Expression ']' | '.' Identifier | Arguments)* | 2707 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 2680 | 2708 |
| 2681 // Parse the initial primary or function expression. | 2709 // Parse the initial primary or function expression. |
| 2682 Expression* result = NULL; | 2710 Expression* result = NULL; |
| 2683 if (peek() == Token::FUNCTION) { | 2711 if (peek() == Token::FUNCTION) { |
| 2684 Expect(Token::FUNCTION, CHECK_OK); | 2712 Expect(Token::FUNCTION, CHECK_OK); |
| 2685 int function_token_position = scanner().location().beg_pos; | 2713 int function_token_position = scanner().location().beg_pos; |
| 2686 Handle<String> name; | 2714 Handle<String> name; |
| 2687 if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK); | 2715 bool is_reserved_name = false; |
| 2688 result = ParseFunctionLiteral(name, function_token_position, | 2716 if (peek_any_identifier()) { |
| 2689 NESTED, CHECK_OK); | 2717 name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK); |
| 2718 } |
| 2719 result = ParseFunctionLiteral(name, is_reserved_name, |
| 2720 function_token_position, NESTED, CHECK_OK); |
| 2690 } else { | 2721 } else { |
| 2691 result = ParsePrimaryExpression(CHECK_OK); | 2722 result = ParsePrimaryExpression(CHECK_OK); |
| 2692 } | 2723 } |
| 2693 | 2724 |
| 2694 while (true) { | 2725 while (true) { |
| 2695 switch (peek()) { | 2726 switch (peek()) { |
| 2696 case Token::LBRACK: { | 2727 case Token::LBRACK: { |
| 2697 Consume(Token::LBRACK); | 2728 Consume(Token::LBRACK); |
| 2698 int pos = scanner().location().beg_pos; | 2729 int pos = scanner().location().beg_pos; |
| 2699 Expression* index = ParseExpression(true, CHECK_OK); | 2730 Expression* index = ParseExpression(true, CHECK_OK); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | 2779 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); |
| 2749 case Token::NUMBER: | 2780 case Token::NUMBER: |
| 2750 return ReportMessage("unexpected_token_number", | 2781 return ReportMessage("unexpected_token_number", |
| 2751 Vector<const char*>::empty()); | 2782 Vector<const char*>::empty()); |
| 2752 case Token::STRING: | 2783 case Token::STRING: |
| 2753 return ReportMessage("unexpected_token_string", | 2784 return ReportMessage("unexpected_token_string", |
| 2754 Vector<const char*>::empty()); | 2785 Vector<const char*>::empty()); |
| 2755 case Token::IDENTIFIER: | 2786 case Token::IDENTIFIER: |
| 2756 return ReportMessage("unexpected_token_identifier", | 2787 return ReportMessage("unexpected_token_identifier", |
| 2757 Vector<const char*>::empty()); | 2788 Vector<const char*>::empty()); |
| 2789 case Token::FUTURE_RESERVED_WORD: |
| 2790 return ReportMessage(temp_scope_->StrictMode() ? |
| 2791 "unexpected_strict_reserved" : |
| 2792 "unexpected_token_identifier", |
| 2793 Vector<const char*>::empty()); |
| 2758 default: | 2794 default: |
| 2759 const char* name = Token::String(token); | 2795 const char* name = Token::String(token); |
| 2760 ASSERT(name != NULL); | 2796 ASSERT(name != NULL); |
| 2761 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | 2797 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); |
| 2762 } | 2798 } |
| 2763 } | 2799 } |
| 2764 | 2800 |
| 2765 | 2801 |
| 2766 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 2802 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
| 2767 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 2803 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 case Token::TRUE_LITERAL: | 2839 case Token::TRUE_LITERAL: |
| 2804 Consume(Token::TRUE_LITERAL); | 2840 Consume(Token::TRUE_LITERAL); |
| 2805 result = new Literal(isolate()->factory()->true_value()); | 2841 result = new Literal(isolate()->factory()->true_value()); |
| 2806 break; | 2842 break; |
| 2807 | 2843 |
| 2808 case Token::FALSE_LITERAL: | 2844 case Token::FALSE_LITERAL: |
| 2809 Consume(Token::FALSE_LITERAL); | 2845 Consume(Token::FALSE_LITERAL); |
| 2810 result = new Literal(isolate()->factory()->false_value()); | 2846 result = new Literal(isolate()->factory()->false_value()); |
| 2811 break; | 2847 break; |
| 2812 | 2848 |
| 2813 case Token::IDENTIFIER: { | 2849 case Token::IDENTIFIER: |
| 2850 case Token::FUTURE_RESERVED_WORD: { |
| 2814 Handle<String> name = ParseIdentifier(CHECK_OK); | 2851 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2815 if (fni_ != NULL) fni_->PushVariableName(name); | 2852 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2816 result = top_scope_->NewUnresolved(name, inside_with()); | 2853 result = top_scope_->NewUnresolved(name, inside_with()); |
| 2817 break; | 2854 break; |
| 2818 } | 2855 } |
| 2819 | 2856 |
| 2820 case Token::NUMBER: { | 2857 case Token::NUMBER: { |
| 2821 Consume(Token::NUMBER); | 2858 Consume(Token::NUMBER); |
| 2822 ASSERT(scanner().is_literal_ascii()); | 2859 ASSERT(scanner().is_literal_ascii()); |
| 2823 double value = StringToDouble(scanner().literal_ascii_string(), | 2860 double value = StringToDouble(scanner().literal_ascii_string(), |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3024 return expression->AsLiteral()->handle(); | 3061 return expression->AsLiteral()->handle(); |
| 3025 } | 3062 } |
| 3026 if (CompileTimeValue::IsCompileTimeValue(expression)) { | 3063 if (CompileTimeValue::IsCompileTimeValue(expression)) { |
| 3027 return CompileTimeValue::GetValue(expression); | 3064 return CompileTimeValue::GetValue(expression); |
| 3028 } | 3065 } |
| 3029 return isolate()->factory()->undefined_value(); | 3066 return isolate()->factory()->undefined_value(); |
| 3030 } | 3067 } |
| 3031 | 3068 |
| 3032 // Defined in ast.cc | 3069 // Defined in ast.cc |
| 3033 bool IsEqualString(void* first, void* second); | 3070 bool IsEqualString(void* first, void* second); |
| 3034 bool IsEqualSmi(void* first, void* second); | 3071 bool IsEqualNumber(void* first, void* second); |
| 3035 | 3072 |
| 3036 | 3073 |
| 3037 // Validation per 11.1.5 Object Initialiser | 3074 // Validation per 11.1.5 Object Initialiser |
| 3038 class ObjectLiteralPropertyChecker { | 3075 class ObjectLiteralPropertyChecker { |
| 3039 public: | 3076 public: |
| 3040 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : | 3077 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : |
| 3041 props(&IsEqualString), | 3078 props(&IsEqualString), |
| 3042 elems(&IsEqualSmi), | 3079 elems(&IsEqualNumber), |
| 3043 parser_(parser), | 3080 parser_(parser), |
| 3044 strict_(strict) { | 3081 strict_(strict) { |
| 3045 } | 3082 } |
| 3046 | 3083 |
| 3047 void CheckProperty( | 3084 void CheckProperty( |
| 3048 ObjectLiteral::Property* property, | 3085 ObjectLiteral::Property* property, |
| 3049 Scanner::Location loc, | 3086 Scanner::Location loc, |
| 3050 bool* ok); | 3087 bool* ok); |
| 3051 | 3088 |
| 3052 private: | 3089 private: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3081 bool* ok) { | 3118 bool* ok) { |
| 3082 | 3119 |
| 3083 ASSERT(property != NULL); | 3120 ASSERT(property != NULL); |
| 3084 | 3121 |
| 3085 Literal *lit = property->key(); | 3122 Literal *lit = property->key(); |
| 3086 Handle<Object> handle = lit->handle(); | 3123 Handle<Object> handle = lit->handle(); |
| 3087 | 3124 |
| 3088 uint32_t hash; | 3125 uint32_t hash; |
| 3089 HashMap* map; | 3126 HashMap* map; |
| 3090 void* key; | 3127 void* key; |
| 3091 Smi* smi_key_location; | |
| 3092 | 3128 |
| 3093 if (handle->IsSymbol()) { | 3129 if (handle->IsSymbol()) { |
| 3094 Handle<String> name(String::cast(*handle)); | 3130 Handle<String> name(String::cast(*handle)); |
| 3095 if (name->AsArrayIndex(&hash)) { | 3131 if (name->AsArrayIndex(&hash)) { |
| 3096 smi_key_location = Smi::FromInt(hash); | 3132 Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash); |
| 3097 key = &smi_key_location; | 3133 key = key_handle.location(); |
| 3098 map = &elems; | 3134 map = &elems; |
| 3099 } else { | 3135 } else { |
| 3100 key = handle.location(); | 3136 key = handle.location(); |
| 3101 hash = name->Hash(); | 3137 hash = name->Hash(); |
| 3102 map = &props; | 3138 map = &props; |
| 3103 } | 3139 } |
| 3104 } else if (handle->ToArrayIndex(&hash)) { | 3140 } else if (handle->ToArrayIndex(&hash)) { |
| 3105 key = handle.location(); | 3141 key = handle.location(); |
| 3106 map = &elems; | 3142 map = &elems; |
| 3107 } else { | 3143 } else { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3211 | 3247 |
| 3212 | 3248 |
| 3213 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, | 3249 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
| 3214 bool* ok) { | 3250 bool* ok) { |
| 3215 // Special handling of getter and setter syntax: | 3251 // Special handling of getter and setter syntax: |
| 3216 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | 3252 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
| 3217 // We have already read the "get" or "set" keyword. | 3253 // We have already read the "get" or "set" keyword. |
| 3218 Token::Value next = Next(); | 3254 Token::Value next = Next(); |
| 3219 bool is_keyword = Token::IsKeyword(next); | 3255 bool is_keyword = Token::IsKeyword(next); |
| 3220 if (next == Token::IDENTIFIER || next == Token::NUMBER || | 3256 if (next == Token::IDENTIFIER || next == Token::NUMBER || |
| 3257 next == Token::FUTURE_RESERVED_WORD || |
| 3221 next == Token::STRING || is_keyword) { | 3258 next == Token::STRING || is_keyword) { |
| 3222 Handle<String> name; | 3259 Handle<String> name; |
| 3223 if (is_keyword) { | 3260 if (is_keyword) { |
| 3224 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); | 3261 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); |
| 3225 } else { | 3262 } else { |
| 3226 name = GetSymbol(CHECK_OK); | 3263 name = GetSymbol(CHECK_OK); |
| 3227 } | 3264 } |
| 3228 FunctionLiteral* value = | 3265 FunctionLiteral* value = |
| 3229 ParseFunctionLiteral(name, | 3266 ParseFunctionLiteral(name, |
| 3267 false, // reserved words are allowed here |
| 3230 RelocInfo::kNoPosition, | 3268 RelocInfo::kNoPosition, |
| 3231 DECLARATION, | 3269 DECLARATION, |
| 3232 CHECK_OK); | 3270 CHECK_OK); |
| 3233 // Allow any number of parameters for compatiabilty with JSC. | 3271 // Allow any number of parameters for compatiabilty with JSC. |
| 3234 // Specification only allows zero parameters for get and one for set. | 3272 // Specification only allows zero parameters for get and one for set. |
| 3235 ObjectLiteral::Property* property = | 3273 ObjectLiteral::Property* property = |
| 3236 new ObjectLiteral::Property(is_getter, value); | 3274 new ObjectLiteral::Property(is_getter, value); |
| 3237 return property; | 3275 return property; |
| 3238 } else { | 3276 } else { |
| 3239 ReportUnexpectedToken(next); | 3277 ReportUnexpectedToken(next); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3262 while (peek() != Token::RBRACE) { | 3300 while (peek() != Token::RBRACE) { |
| 3263 if (fni_ != NULL) fni_->Enter(); | 3301 if (fni_ != NULL) fni_->Enter(); |
| 3264 | 3302 |
| 3265 Literal* key = NULL; | 3303 Literal* key = NULL; |
| 3266 Token::Value next = peek(); | 3304 Token::Value next = peek(); |
| 3267 | 3305 |
| 3268 // Location of the property name token | 3306 // Location of the property name token |
| 3269 Scanner::Location loc = scanner().peek_location(); | 3307 Scanner::Location loc = scanner().peek_location(); |
| 3270 | 3308 |
| 3271 switch (next) { | 3309 switch (next) { |
| 3310 case Token::FUTURE_RESERVED_WORD: |
| 3272 case Token::IDENTIFIER: { | 3311 case Token::IDENTIFIER: { |
| 3273 bool is_getter = false; | 3312 bool is_getter = false; |
| 3274 bool is_setter = false; | 3313 bool is_setter = false; |
| 3275 Handle<String> id = | 3314 Handle<String> id = |
| 3276 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3315 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3277 if (fni_ != NULL) fni_->PushLiteralName(id); | 3316 if (fni_ != NULL) fni_->PushLiteralName(id); |
| 3278 | 3317 |
| 3279 if ((is_getter || is_setter) && peek() != Token::COLON) { | 3318 if ((is_getter || is_setter) && peek() != Token::COLON) { |
| 3280 // Update loc to point to the identifier | 3319 // Update loc to point to the identifier |
| 3281 loc = scanner().peek_location(); | 3320 loc = scanner().peek_location(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3410 result->Add(argument); | 3449 result->Add(argument); |
| 3411 done = (peek() == Token::RPAREN); | 3450 done = (peek() == Token::RPAREN); |
| 3412 if (!done) Expect(Token::COMMA, CHECK_OK); | 3451 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3413 } | 3452 } |
| 3414 Expect(Token::RPAREN, CHECK_OK); | 3453 Expect(Token::RPAREN, CHECK_OK); |
| 3415 return result; | 3454 return result; |
| 3416 } | 3455 } |
| 3417 | 3456 |
| 3418 | 3457 |
| 3419 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, | 3458 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, |
| 3459 bool name_is_reserved, |
| 3420 int function_token_position, | 3460 int function_token_position, |
| 3421 FunctionLiteralType type, | 3461 FunctionLiteralType type, |
| 3422 bool* ok) { | 3462 bool* ok) { |
| 3423 // Function :: | 3463 // Function :: |
| 3424 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3464 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3425 bool is_named = !var_name.is_null(); | 3465 bool is_named = !var_name.is_null(); |
| 3426 | 3466 |
| 3427 // The name associated with this function. If it's a function expression, | 3467 // The name associated with this function. If it's a function expression, |
| 3428 // this is the actual function name, otherwise this is the name of the | 3468 // this is the actual function name, otherwise this is the name of the |
| 3429 // variable declared and initialized with the function (expression). In | 3469 // variable declared and initialized with the function (expression). In |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3444 scope); | 3484 scope); |
| 3445 TemporaryScope temp_scope(&this->temp_scope_); | 3485 TemporaryScope temp_scope(&this->temp_scope_); |
| 3446 top_scope_->SetScopeName(name); | 3486 top_scope_->SetScopeName(name); |
| 3447 | 3487 |
| 3448 // FormalParameterList :: | 3488 // FormalParameterList :: |
| 3449 // '(' (Identifier)*[','] ')' | 3489 // '(' (Identifier)*[','] ')' |
| 3450 Expect(Token::LPAREN, CHECK_OK); | 3490 Expect(Token::LPAREN, CHECK_OK); |
| 3451 int start_pos = scanner().location().beg_pos; | 3491 int start_pos = scanner().location().beg_pos; |
| 3452 Scanner::Location name_loc = Scanner::NoLocation(); | 3492 Scanner::Location name_loc = Scanner::NoLocation(); |
| 3453 Scanner::Location dupe_loc = Scanner::NoLocation(); | 3493 Scanner::Location dupe_loc = Scanner::NoLocation(); |
| 3494 Scanner::Location reserved_loc = Scanner::NoLocation(); |
| 3454 | 3495 |
| 3455 bool done = (peek() == Token::RPAREN); | 3496 bool done = (peek() == Token::RPAREN); |
| 3456 while (!done) { | 3497 while (!done) { |
| 3457 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3498 bool is_reserved = false; |
| 3499 Handle<String> param_name = |
| 3500 ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); |
| 3458 | 3501 |
| 3459 // Store locations for possible future error reports. | 3502 // Store locations for possible future error reports. |
| 3460 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { | 3503 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { |
| 3461 name_loc = scanner().location(); | 3504 name_loc = scanner().location(); |
| 3462 } | 3505 } |
| 3463 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 3506 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 3464 dupe_loc = scanner().location(); | 3507 dupe_loc = scanner().location(); |
| 3465 } | 3508 } |
| 3509 if (!reserved_loc.IsValid() && is_reserved) { |
| 3510 reserved_loc = scanner().location(); |
| 3511 } |
| 3466 | 3512 |
| 3467 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); | 3513 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); |
| 3468 top_scope_->AddParameter(parameter); | 3514 top_scope_->AddParameter(parameter); |
| 3469 num_parameters++; | 3515 num_parameters++; |
| 3516 if (num_parameters > kMaxNumFunctionParameters) { |
| 3517 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 3518 Vector<const char*>::empty()); |
| 3519 *ok = false; |
| 3520 return NULL; |
| 3521 } |
| 3470 done = (peek() == Token::RPAREN); | 3522 done = (peek() == Token::RPAREN); |
| 3471 if (!done) Expect(Token::COMMA, CHECK_OK); | 3523 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3472 } | 3524 } |
| 3473 Expect(Token::RPAREN, CHECK_OK); | 3525 Expect(Token::RPAREN, CHECK_OK); |
| 3474 | 3526 |
| 3475 Expect(Token::LBRACE, CHECK_OK); | 3527 Expect(Token::LBRACE, CHECK_OK); |
| 3476 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); | 3528 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); |
| 3477 | 3529 |
| 3478 // If we have a named function expression, we add a local variable | 3530 // If we have a named function expression, we add a local variable |
| 3479 // declaration to the body of the function with the name of the | 3531 // declaration to the body of the function with the name of the |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3537 Expect(Token::RBRACE, CHECK_OK); | 3589 Expect(Token::RBRACE, CHECK_OK); |
| 3538 end_pos = scanner().location().end_pos; | 3590 end_pos = scanner().location().end_pos; |
| 3539 } | 3591 } |
| 3540 | 3592 |
| 3541 // Validate strict mode. | 3593 // Validate strict mode. |
| 3542 if (temp_scope_->StrictMode()) { | 3594 if (temp_scope_->StrictMode()) { |
| 3543 if (IsEvalOrArguments(name)) { | 3595 if (IsEvalOrArguments(name)) { |
| 3544 int position = function_token_position != RelocInfo::kNoPosition | 3596 int position = function_token_position != RelocInfo::kNoPosition |
| 3545 ? function_token_position | 3597 ? function_token_position |
| 3546 : (start_pos > 0 ? start_pos - 1 : start_pos); | 3598 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3547 ReportMessageAt(Scanner::Location(position, start_pos), | 3599 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3600 ReportMessageAt(location, |
| 3548 "strict_function_name", Vector<const char*>::empty()); | 3601 "strict_function_name", Vector<const char*>::empty()); |
| 3549 *ok = false; | 3602 *ok = false; |
| 3550 return NULL; | 3603 return NULL; |
| 3551 } | 3604 } |
| 3552 if (name_loc.IsValid()) { | 3605 if (name_loc.IsValid()) { |
| 3553 ReportMessageAt(name_loc, "strict_param_name", | 3606 ReportMessageAt(name_loc, "strict_param_name", |
| 3554 Vector<const char*>::empty()); | 3607 Vector<const char*>::empty()); |
| 3555 *ok = false; | 3608 *ok = false; |
| 3556 return NULL; | 3609 return NULL; |
| 3557 } | 3610 } |
| 3558 if (dupe_loc.IsValid()) { | 3611 if (dupe_loc.IsValid()) { |
| 3559 ReportMessageAt(dupe_loc, "strict_param_dupe", | 3612 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 3560 Vector<const char*>::empty()); | 3613 Vector<const char*>::empty()); |
| 3561 *ok = false; | 3614 *ok = false; |
| 3562 return NULL; | 3615 return NULL; |
| 3563 } | 3616 } |
| 3617 if (name_is_reserved) { |
| 3618 int position = function_token_position != RelocInfo::kNoPosition |
| 3619 ? function_token_position |
| 3620 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3621 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3622 ReportMessageAt(location, "strict_reserved_word", |
| 3623 Vector<const char*>::empty()); |
| 3624 *ok = false; |
| 3625 return NULL; |
| 3626 } |
| 3627 if (reserved_loc.IsValid()) { |
| 3628 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3629 Vector<const char*>::empty()); |
| 3630 *ok = false; |
| 3631 return NULL; |
| 3632 } |
| 3564 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3633 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
| 3565 } | 3634 } |
| 3566 | 3635 |
| 3567 FunctionLiteral* function_literal = | 3636 FunctionLiteral* function_literal = |
| 3568 new FunctionLiteral(name, | 3637 new FunctionLiteral(name, |
| 3569 top_scope_, | 3638 top_scope_, |
| 3570 body, | 3639 body, |
| 3571 materialized_literal_count, | 3640 materialized_literal_count, |
| 3572 expected_property_count, | 3641 expected_property_count, |
| 3573 only_simple_this_property_assignments, | 3642 only_simple_this_property_assignments, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3625 ReportMessage("illegal_access", Vector<const char*>::empty()); | 3694 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 3626 *ok = false; | 3695 *ok = false; |
| 3627 return NULL; | 3696 return NULL; |
| 3628 } | 3697 } |
| 3629 | 3698 |
| 3630 // We have a valid intrinsics call or a call to a builtin. | 3699 // We have a valid intrinsics call or a call to a builtin. |
| 3631 return new CallRuntime(name, function, args); | 3700 return new CallRuntime(name, function, args); |
| 3632 } | 3701 } |
| 3633 | 3702 |
| 3634 | 3703 |
| 3704 bool Parser::peek_any_identifier() { |
| 3705 Token::Value next = peek(); |
| 3706 return next == Token::IDENTIFIER || |
| 3707 next == Token::FUTURE_RESERVED_WORD; |
| 3708 } |
| 3709 |
| 3710 |
| 3635 void Parser::Consume(Token::Value token) { | 3711 void Parser::Consume(Token::Value token) { |
| 3636 Token::Value next = Next(); | 3712 Token::Value next = Next(); |
| 3637 USE(next); | 3713 USE(next); |
| 3638 USE(token); | 3714 USE(token); |
| 3639 ASSERT(next == token); | 3715 ASSERT(next == token); |
| 3640 } | 3716 } |
| 3641 | 3717 |
| 3642 | 3718 |
| 3643 void Parser::Expect(Token::Value token, bool* ok) { | 3719 void Parser::Expect(Token::Value token, bool* ok) { |
| 3644 Token::Value next = Next(); | 3720 Token::Value next = Next(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3684 return new Literal(isolate()->factory()->the_hole_value()); | 3760 return new Literal(isolate()->factory()->the_hole_value()); |
| 3685 } | 3761 } |
| 3686 | 3762 |
| 3687 | 3763 |
| 3688 Literal* Parser::GetLiteralNumber(double value) { | 3764 Literal* Parser::GetLiteralNumber(double value) { |
| 3689 return NewNumberLiteral(value); | 3765 return NewNumberLiteral(value); |
| 3690 } | 3766 } |
| 3691 | 3767 |
| 3692 | 3768 |
| 3693 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3769 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3694 Expect(Token::IDENTIFIER, ok); | 3770 bool is_reserved; |
| 3771 return ParseIdentifierOrReservedWord(&is_reserved, ok); |
| 3772 } |
| 3773 |
| 3774 |
| 3775 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, |
| 3776 bool* ok) { |
| 3777 *is_reserved = false; |
| 3778 if (temp_scope_->StrictMode()) { |
| 3779 Expect(Token::IDENTIFIER, ok); |
| 3780 } else { |
| 3781 if (!Check(Token::IDENTIFIER)) { |
| 3782 Expect(Token::FUTURE_RESERVED_WORD, ok); |
| 3783 *is_reserved = true; |
| 3784 } |
| 3785 } |
| 3695 if (!*ok) return Handle<String>(); | 3786 if (!*ok) return Handle<String>(); |
| 3696 return GetSymbol(ok); | 3787 return GetSymbol(ok); |
| 3697 } | 3788 } |
| 3698 | 3789 |
| 3699 | 3790 |
| 3700 Handle<String> Parser::ParseIdentifierName(bool* ok) { | 3791 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
| 3701 Token::Value next = Next(); | 3792 Token::Value next = Next(); |
| 3702 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { | 3793 if (next != Token::IDENTIFIER && |
| 3794 next != Token::FUTURE_RESERVED_WORD && |
| 3795 !Token::IsKeyword(next)) { |
| 3703 ReportUnexpectedToken(next); | 3796 ReportUnexpectedToken(next); |
| 3704 *ok = false; | 3797 *ok = false; |
| 3705 return Handle<String>(); | 3798 return Handle<String>(); |
| 3706 } | 3799 } |
| 3707 return GetSymbol(ok); | 3800 return GetSymbol(ok); |
| 3708 } | 3801 } |
| 3709 | 3802 |
| 3803 |
| 3804 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 3805 // in strict mode. |
| 3806 void Parser::CheckStrictModeLValue(Expression* expression, |
| 3807 const char* error, |
| 3808 bool* ok) { |
| 3809 ASSERT(temp_scope_->StrictMode()); |
| 3810 VariableProxy* lhs = expression != NULL |
| 3811 ? expression->AsVariableProxy() |
| 3812 : NULL; |
| 3813 |
| 3814 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 3815 ReportMessage(error, Vector<const char*>::empty()); |
| 3816 *ok = false; |
| 3817 } |
| 3818 } |
| 3819 |
| 3820 |
| 3710 // Checks whether octal literal last seen is between beg_pos and end_pos. | 3821 // Checks whether octal literal last seen is between beg_pos and end_pos. |
| 3711 // If so, reports an error. | 3822 // If so, reports an error. |
| 3712 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 3823 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 3713 int octal = scanner().octal_position(); | 3824 int octal = scanner().octal_position(); |
| 3714 if (beg_pos <= octal && octal <= end_pos) { | 3825 if (beg_pos <= octal && octal <= end_pos) { |
| 3715 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", | 3826 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", |
| 3716 Vector<const char*>::empty()); | 3827 Vector<const char*>::empty()); |
| 3717 scanner().clear_octal_position(); | 3828 scanner().clear_octal_position(); |
| 3718 *ok = false; | 3829 *ok = false; |
| 3719 } | 3830 } |
| 3720 } | 3831 } |
| 3721 | 3832 |
| 3722 | 3833 |
| 3723 // This function reads an identifier and determines whether or not it | 3834 // This function reads an identifier and determines whether or not it |
| 3724 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 3835 // is 'get' or 'set'. |
| 3725 // checking on the output is that this involves heap allocation which | |
| 3726 // we can't do during preparsing. | |
| 3727 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 3836 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
| 3728 bool* is_set, | 3837 bool* is_set, |
| 3729 bool* ok) { | 3838 bool* ok) { |
| 3730 Expect(Token::IDENTIFIER, ok); | 3839 Handle<String> result = ParseIdentifier(ok); |
| 3731 if (!*ok) return Handle<String>(); | 3840 if (!*ok) return Handle<String>(); |
| 3732 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { | 3841 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { |
| 3733 const char* token = scanner().literal_ascii_string().start(); | 3842 const char* token = scanner().literal_ascii_string().start(); |
| 3734 *is_get = strncmp(token, "get", 3) == 0; | 3843 *is_get = strncmp(token, "get", 3) == 0; |
| 3735 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 3844 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 3736 } | 3845 } |
| 3737 return GetSymbol(ok); | 3846 return result; |
| 3738 } | 3847 } |
| 3739 | 3848 |
| 3740 | 3849 |
| 3741 // ---------------------------------------------------------------------------- | 3850 // ---------------------------------------------------------------------------- |
| 3742 // Parser support | 3851 // Parser support |
| 3743 | 3852 |
| 3744 | 3853 |
| 3745 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 3854 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| 3746 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 3855 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 3747 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 3856 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3871 case Token::EOS: | 3980 case Token::EOS: |
| 3872 message = "unexpected_eos"; | 3981 message = "unexpected_eos"; |
| 3873 break; | 3982 break; |
| 3874 case Token::NUMBER: | 3983 case Token::NUMBER: |
| 3875 message = "unexpected_token_number"; | 3984 message = "unexpected_token_number"; |
| 3876 break; | 3985 break; |
| 3877 case Token::STRING: | 3986 case Token::STRING: |
| 3878 message = "unexpected_token_string"; | 3987 message = "unexpected_token_string"; |
| 3879 break; | 3988 break; |
| 3880 case Token::IDENTIFIER: | 3989 case Token::IDENTIFIER: |
| 3990 case Token::FUTURE_RESERVED_WORD: |
| 3881 message = "unexpected_token_identifier"; | 3991 message = "unexpected_token_identifier"; |
| 3882 break; | 3992 break; |
| 3883 default: | 3993 default: |
| 3884 message = "unexpected_token"; | 3994 message = "unexpected_token"; |
| 3885 name_opt = Token::String(token); | 3995 name_opt = Token::String(token); |
| 3886 ASSERT(name_opt != NULL); | 3996 ASSERT(name_opt != NULL); |
| 3887 break; | 3997 break; |
| 3888 } | 3998 } |
| 3889 | 3999 |
| 3890 Scanner::Location source_location = scanner_.location(); | 4000 Scanner::Location source_location = scanner_.location(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3921 return isolate()->factory()->NewStringFromTwoByte( | 4031 return isolate()->factory()->NewStringFromTwoByte( |
| 3922 scanner_.literal_uc16_string()); | 4032 scanner_.literal_uc16_string()); |
| 3923 } | 4033 } |
| 3924 } | 4034 } |
| 3925 | 4035 |
| 3926 | 4036 |
| 3927 // Parse any JSON value. | 4037 // Parse any JSON value. |
| 3928 Handle<Object> JsonParser::ParseJsonValue() { | 4038 Handle<Object> JsonParser::ParseJsonValue() { |
| 3929 Token::Value token = scanner_.Next(); | 4039 Token::Value token = scanner_.Next(); |
| 3930 switch (token) { | 4040 switch (token) { |
| 3931 case Token::STRING: { | 4041 case Token::STRING: |
| 3932 return GetString(); | 4042 return GetString(); |
| 3933 } | 4043 case Token::NUMBER: |
| 3934 case Token::NUMBER: { | 4044 return isolate()->factory()->NewNumber(scanner_.number()); |
| 3935 ASSERT(scanner_.is_literal_ascii()); | |
| 3936 double value = StringToDouble(scanner_.literal_ascii_string(), | |
| 3937 NO_FLAGS, // Hex, octal or trailing junk. | |
| 3938 OS::nan_value()); | |
| 3939 return isolate()->factory()->NewNumber(value); | |
| 3940 } | |
| 3941 case Token::FALSE_LITERAL: | 4045 case Token::FALSE_LITERAL: |
| 3942 return isolate()->factory()->false_value(); | 4046 return isolate()->factory()->false_value(); |
| 3943 case Token::TRUE_LITERAL: | 4047 case Token::TRUE_LITERAL: |
| 3944 return isolate()->factory()->true_value(); | 4048 return isolate()->factory()->true_value(); |
| 3945 case Token::NULL_LITERAL: | 4049 case Token::NULL_LITERAL: |
| 3946 return isolate()->factory()->null_value(); | 4050 return isolate()->factory()->null_value(); |
| 3947 case Token::LBRACE: | 4051 case Token::LBRACE: |
| 3948 return ParseJsonObject(); | 4052 return ParseJsonObject(); |
| 3949 case Token::LBRACK: | 4053 case Token::LBRACK: |
| 3950 return ParseJsonArray(); | 4054 return ParseJsonArray(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3973 } | 4077 } |
| 3974 Handle<String> key = GetString(); | 4078 Handle<String> key = GetString(); |
| 3975 if (scanner_.Next() != Token::COLON) { | 4079 if (scanner_.Next() != Token::COLON) { |
| 3976 return ReportUnexpectedToken(); | 4080 return ReportUnexpectedToken(); |
| 3977 } | 4081 } |
| 3978 Handle<Object> value = ParseJsonValue(); | 4082 Handle<Object> value = ParseJsonValue(); |
| 3979 if (value.is_null()) return Handle<Object>::null(); | 4083 if (value.is_null()) return Handle<Object>::null(); |
| 3980 uint32_t index; | 4084 uint32_t index; |
| 3981 if (key->AsArrayIndex(&index)) { | 4085 if (key->AsArrayIndex(&index)) { |
| 3982 SetOwnElement(json_object, index, value); | 4086 SetOwnElement(json_object, index, value); |
| 4087 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { |
| 4088 // We can't remove the __proto__ accessor since it's hardcoded |
| 4089 // in several places. Instead go along and add the value as |
| 4090 // the prototype of the created object if possible. |
| 4091 SetPrototype(json_object, value); |
| 3983 } else { | 4092 } else { |
| 3984 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); | 4093 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); |
| 3985 } | 4094 } |
| 3986 } while (scanner_.Next() == Token::COMMA); | 4095 } while (scanner_.Next() == Token::COMMA); |
| 3987 if (scanner_.current_token() != Token::RBRACE) { | 4096 if (scanner_.current_token() != Token::RBRACE) { |
| 3988 return ReportUnexpectedToken(); | 4097 return ReportUnexpectedToken(); |
| 3989 } | 4098 } |
| 3990 } | 4099 } |
| 3991 return json_object; | 4100 return json_object; |
| 3992 } | 4101 } |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4984 Vector<const char*> args = pre_data->BuildArgs(); | 5093 Vector<const char*> args = pre_data->BuildArgs(); |
| 4985 parser.ReportMessageAt(loc, message, args); | 5094 parser.ReportMessageAt(loc, message, args); |
| 4986 DeleteArray(message); | 5095 DeleteArray(message); |
| 4987 for (int i = 0; i < args.length(); i++) { | 5096 for (int i = 0; i < args.length(); i++) { |
| 4988 DeleteArray(args[i]); | 5097 DeleteArray(args[i]); |
| 4989 } | 5098 } |
| 4990 DeleteArray(args.start()); | 5099 DeleteArray(args.start()); |
| 4991 ASSERT(info->isolate()->has_pending_exception()); | 5100 ASSERT(info->isolate()->has_pending_exception()); |
| 4992 } else { | 5101 } else { |
| 4993 Handle<String> source = Handle<String>(String::cast(script->source())); | 5102 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4994 result = parser.ParseProgram(source, info->is_global()); | 5103 result = parser.ParseProgram(source, |
| 5104 info->is_global(), |
| 5105 info->StrictMode()); |
| 4995 } | 5106 } |
| 4996 } | 5107 } |
| 4997 | 5108 |
| 4998 info->SetFunction(result); | 5109 info->SetFunction(result); |
| 4999 return (result != NULL); | 5110 return (result != NULL); |
| 5000 } | 5111 } |
| 5001 | 5112 |
| 5002 } } // namespace v8::internal | 5113 } } // namespace v8::internal |
| OLD | NEW |