| 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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 friend class Target; | 334 friend class Target; |
| 335 friend class TargetScope; | 335 friend class TargetScope; |
| 336 friend class LexicalScope; | 336 friend class LexicalScope; |
| 337 friend class TemporaryScope; | 337 friend class TemporaryScope; |
| 338 }; | 338 }; |
| 339 | 339 |
| 340 | 340 |
| 341 template <typename T, int initial_size> | 341 template <typename T, int initial_size> |
| 342 class BufferedZoneList { | 342 class BufferedZoneList { |
| 343 public: | 343 public: |
| 344 | 344 BufferedZoneList() : list_(NULL), last_(NULL) {} |
| 345 BufferedZoneList() : | |
| 346 list_(NULL), last_(NULL) {} | |
| 347 | 345 |
| 348 // Adds element at end of list. This element is buffered and can | 346 // Adds element at end of list. This element is buffered and can |
| 349 // be read using last() or removed using RemoveLast until a new Add or until | 347 // be read using last() or removed using RemoveLast until a new Add or until |
| 350 // RemoveLast or GetList has been called. | 348 // RemoveLast or GetList has been called. |
| 351 void Add(T* value) { | 349 void Add(T* value) { |
| 352 if (last_ != NULL) { | 350 if (last_ != NULL) { |
| 353 if (list_ == NULL) { | 351 if (list_ == NULL) { |
| 354 list_ = new ZoneList<T*>(initial_size); | 352 list_ = new ZoneList<T*>(initial_size); |
| 355 } | 353 } |
| 356 list_->Add(last_); | 354 list_->Add(last_); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 last_ = NULL; | 405 last_ = NULL; |
| 408 } | 406 } |
| 409 return list_; | 407 return list_; |
| 410 } | 408 } |
| 411 | 409 |
| 412 private: | 410 private: |
| 413 ZoneList<T*>* list_; | 411 ZoneList<T*>* list_; |
| 414 T* last_; | 412 T* last_; |
| 415 }; | 413 }; |
| 416 | 414 |
| 415 |
| 417 // Accumulates RegExp atoms and assertions into lists of terms and alternatives. | 416 // Accumulates RegExp atoms and assertions into lists of terms and alternatives. |
| 418 class RegExpBuilder: public ZoneObject { | 417 class RegExpBuilder: public ZoneObject { |
| 419 public: | 418 public: |
| 420 RegExpBuilder(); | 419 RegExpBuilder(); |
| 421 void AddCharacter(uc16 character); | 420 void AddCharacter(uc16 character); |
| 422 // "Adds" an empty expression. Does nothing except consume a | 421 // "Adds" an empty expression. Does nothing except consume a |
| 423 // following quantifier | 422 // following quantifier |
| 424 void AddEmpty(); | 423 void AddEmpty(); |
| 425 void AddAtom(RegExpTree* tree); | 424 void AddAtom(RegExpTree* tree); |
| 426 void AddAssertion(RegExpTree* tree); | 425 void AddAssertion(RegExpTree* tree); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 // Only use if the result of the parse is a single atom node. | 644 // Only use if the result of the parse is a single atom node. |
| 646 bool simple(); | 645 bool simple(); |
| 647 bool contains_anchor() { return contains_anchor_; } | 646 bool contains_anchor() { return contains_anchor_; } |
| 648 void set_contains_anchor() { contains_anchor_ = true; } | 647 void set_contains_anchor() { contains_anchor_ = true; } |
| 649 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } | 648 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } |
| 650 int position() { return next_pos_ - 1; } | 649 int position() { return next_pos_ - 1; } |
| 651 bool failed() { return failed_; } | 650 bool failed() { return failed_; } |
| 652 | 651 |
| 653 static const int kMaxCaptures = 1 << 16; | 652 static const int kMaxCaptures = 1 << 16; |
| 654 static const uc32 kEndMarker = (1 << 21); | 653 static const uc32 kEndMarker = (1 << 21); |
| 654 |
| 655 private: | 655 private: |
| 656 enum SubexpressionType { | 656 enum SubexpressionType { |
| 657 INITIAL, | 657 INITIAL, |
| 658 CAPTURE, // All positive values represent captures. | 658 CAPTURE, // All positive values represent captures. |
| 659 POSITIVE_LOOKAHEAD, | 659 POSITIVE_LOOKAHEAD, |
| 660 NEGATIVE_LOOKAHEAD, | 660 NEGATIVE_LOOKAHEAD, |
| 661 GROUPING | 661 GROUPING |
| 662 }; | 662 }; |
| 663 | 663 |
| 664 class RegExpParserState : public ZoneObject { | 664 class RegExpParserState : public ZoneObject { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 } | 740 } |
| 741 bool only_simple_this_property_assignments() { | 741 bool only_simple_this_property_assignments() { |
| 742 return only_simple_this_property_assignments_; | 742 return only_simple_this_property_assignments_; |
| 743 } | 743 } |
| 744 Handle<FixedArray> this_property_assignments() { | 744 Handle<FixedArray> this_property_assignments() { |
| 745 return this_property_assignments_; | 745 return this_property_assignments_; |
| 746 } | 746 } |
| 747 | 747 |
| 748 void AddProperty() { expected_property_count_++; } | 748 void AddProperty() { expected_property_count_++; } |
| 749 int expected_property_count() { return expected_property_count_; } | 749 int expected_property_count() { return expected_property_count_; } |
| 750 |
| 751 void AddLoop() { loop_count_++; } |
| 752 bool ContainsLoops() const { return loop_count_ > 0; } |
| 753 |
| 750 private: | 754 private: |
| 751 // Captures the number of literals that need materialization in the | 755 // Captures the number of literals that need materialization in the |
| 752 // function. Includes regexp literals, and boilerplate for object | 756 // function. Includes regexp literals, and boilerplate for object |
| 753 // and array literals. | 757 // and array literals. |
| 754 int materialized_literal_count_; | 758 int materialized_literal_count_; |
| 755 | 759 |
| 756 // Properties count estimation. | 760 // Properties count estimation. |
| 757 int expected_property_count_; | 761 int expected_property_count_; |
| 758 | 762 |
| 763 // Keeps track of assignments to properties of this. Used for |
| 764 // optimizing constructors. |
| 759 bool only_simple_this_property_assignments_; | 765 bool only_simple_this_property_assignments_; |
| 760 Handle<FixedArray> this_property_assignments_; | 766 Handle<FixedArray> this_property_assignments_; |
| 761 | 767 |
| 768 // Captures the number of loops inside the scope. |
| 769 int loop_count_; |
| 770 |
| 762 // Bookkeeping | 771 // Bookkeeping |
| 763 Parser* parser_; | 772 Parser* parser_; |
| 764 TemporaryScope* parent_; | 773 TemporaryScope* parent_; |
| 765 | 774 |
| 766 friend class Parser; | 775 friend class Parser; |
| 767 }; | 776 }; |
| 768 | 777 |
| 769 | 778 |
| 770 TemporaryScope::TemporaryScope(Parser* parser) | 779 TemporaryScope::TemporaryScope(Parser* parser) |
| 771 : materialized_literal_count_(0), | 780 : materialized_literal_count_(0), |
| 772 expected_property_count_(0), | 781 expected_property_count_(0), |
| 773 only_simple_this_property_assignments_(false), | 782 only_simple_this_property_assignments_(false), |
| 774 this_property_assignments_(Factory::empty_fixed_array()), | 783 this_property_assignments_(Factory::empty_fixed_array()), |
| 784 loop_count_(0), |
| 775 parser_(parser), | 785 parser_(parser), |
| 776 parent_(parser->temp_scope_) { | 786 parent_(parser->temp_scope_) { |
| 777 parser->temp_scope_ = this; | 787 parser->temp_scope_ = this; |
| 778 } | 788 } |
| 779 | 789 |
| 780 | 790 |
| 781 TemporaryScope::~TemporaryScope() { | 791 TemporaryScope::~TemporaryScope() { |
| 782 parser_->temp_scope_ = parent_; | 792 parser_->temp_scope_ = parent_; |
| 783 } | 793 } |
| 784 | 794 |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 no_name, | 1285 no_name, |
| 1276 top_scope_, | 1286 top_scope_, |
| 1277 body.elements(), | 1287 body.elements(), |
| 1278 temp_scope.materialized_literal_count(), | 1288 temp_scope.materialized_literal_count(), |
| 1279 temp_scope.expected_property_count(), | 1289 temp_scope.expected_property_count(), |
| 1280 temp_scope.only_simple_this_property_assignments(), | 1290 temp_scope.only_simple_this_property_assignments(), |
| 1281 temp_scope.this_property_assignments(), | 1291 temp_scope.this_property_assignments(), |
| 1282 0, | 1292 0, |
| 1283 0, | 1293 0, |
| 1284 source->length(), | 1294 source->length(), |
| 1285 false)); | 1295 false, |
| 1296 temp_scope.ContainsLoops())); |
| 1286 } else if (scanner().stack_overflow()) { | 1297 } else if (scanner().stack_overflow()) { |
| 1287 Top::StackOverflow(); | 1298 Top::StackOverflow(); |
| 1288 } | 1299 } |
| 1289 } | 1300 } |
| 1290 | 1301 |
| 1291 // Make sure the target stack is empty. | 1302 // Make sure the target stack is empty. |
| 1292 ASSERT(target_stack_ == NULL); | 1303 ASSERT(target_stack_ == NULL); |
| 1293 | 1304 |
| 1294 // If there was a syntax error we have to get rid of the AST | 1305 // If there was a syntax error we have to get rid of the AST |
| 1295 // and it is not safe to do so before the scope has been deleted. | 1306 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 no_name, | 1386 no_name, |
| 1376 top_scope_, | 1387 top_scope_, |
| 1377 statement.elements(), | 1388 statement.elements(), |
| 1378 temp_scope.materialized_literal_count(), | 1389 temp_scope.materialized_literal_count(), |
| 1379 temp_scope.expected_property_count(), | 1390 temp_scope.expected_property_count(), |
| 1380 temp_scope.only_simple_this_property_assignments(), | 1391 temp_scope.only_simple_this_property_assignments(), |
| 1381 temp_scope.this_property_assignments(), | 1392 temp_scope.this_property_assignments(), |
| 1382 0, | 1393 0, |
| 1383 0, | 1394 0, |
| 1384 source->length(), | 1395 source->length(), |
| 1385 false)); | 1396 false, |
| 1397 temp_scope.ContainsLoops())); |
| 1386 } else if (scanner().stack_overflow()) { | 1398 } else if (scanner().stack_overflow()) { |
| 1387 Top::StackOverflow(); | 1399 Top::StackOverflow(); |
| 1388 } | 1400 } |
| 1389 } | 1401 } |
| 1390 | 1402 |
| 1391 // Make sure the target stack is empty. | 1403 // Make sure the target stack is empty. |
| 1392 ASSERT(target_stack_ == NULL); | 1404 ASSERT(target_stack_ == NULL); |
| 1393 | 1405 |
| 1394 // If there was a syntax error we have to get rid of the AST | 1406 // If there was a syntax error we have to get rid of the AST |
| 1395 // and it is not safe to do so before the scope has been deleted. | 1407 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2646 | 2658 |
| 2647 return result; | 2659 return result; |
| 2648 } | 2660 } |
| 2649 | 2661 |
| 2650 | 2662 |
| 2651 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2663 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2652 bool* ok) { | 2664 bool* ok) { |
| 2653 // DoStatement :: | 2665 // DoStatement :: |
| 2654 // 'do' Statement 'while' '(' Expression ')' ';' | 2666 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2655 | 2667 |
| 2668 temp_scope_->AddLoop(); |
| 2656 DoWhileStatement* loop = NEW(DoWhileStatement(labels)); | 2669 DoWhileStatement* loop = NEW(DoWhileStatement(labels)); |
| 2657 Target target(this, loop); | 2670 Target target(this, loop); |
| 2658 | 2671 |
| 2659 Expect(Token::DO, CHECK_OK); | 2672 Expect(Token::DO, CHECK_OK); |
| 2660 Statement* body = ParseStatement(NULL, CHECK_OK); | 2673 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2661 Expect(Token::WHILE, CHECK_OK); | 2674 Expect(Token::WHILE, CHECK_OK); |
| 2662 Expect(Token::LPAREN, CHECK_OK); | 2675 Expect(Token::LPAREN, CHECK_OK); |
| 2663 | 2676 |
| 2664 if (loop != NULL) { | 2677 if (loop != NULL) { |
| 2665 int position = scanner().location().beg_pos; | 2678 int position = scanner().location().beg_pos; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2678 | 2691 |
| 2679 if (loop != NULL) loop->Initialize(cond, body); | 2692 if (loop != NULL) loop->Initialize(cond, body); |
| 2680 return loop; | 2693 return loop; |
| 2681 } | 2694 } |
| 2682 | 2695 |
| 2683 | 2696 |
| 2684 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2697 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2685 // WhileStatement :: | 2698 // WhileStatement :: |
| 2686 // 'while' '(' Expression ')' Statement | 2699 // 'while' '(' Expression ')' Statement |
| 2687 | 2700 |
| 2701 temp_scope_->AddLoop(); |
| 2688 WhileStatement* loop = NEW(WhileStatement(labels)); | 2702 WhileStatement* loop = NEW(WhileStatement(labels)); |
| 2689 Target target(this, loop); | 2703 Target target(this, loop); |
| 2690 | 2704 |
| 2691 Expect(Token::WHILE, CHECK_OK); | 2705 Expect(Token::WHILE, CHECK_OK); |
| 2692 Expect(Token::LPAREN, CHECK_OK); | 2706 Expect(Token::LPAREN, CHECK_OK); |
| 2693 Expression* cond = ParseExpression(true, CHECK_OK); | 2707 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2694 if (cond != NULL) cond->set_is_loop_condition(true); | 2708 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2695 Expect(Token::RPAREN, CHECK_OK); | 2709 Expect(Token::RPAREN, CHECK_OK); |
| 2696 Statement* body = ParseStatement(NULL, CHECK_OK); | 2710 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2697 | 2711 |
| 2698 if (loop != NULL) loop->Initialize(cond, body); | 2712 if (loop != NULL) loop->Initialize(cond, body); |
| 2699 return loop; | 2713 return loop; |
| 2700 } | 2714 } |
| 2701 | 2715 |
| 2702 | 2716 |
| 2703 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2717 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2704 // ForStatement :: | 2718 // ForStatement :: |
| 2705 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2719 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2706 | 2720 |
| 2721 temp_scope_->AddLoop(); |
| 2707 Statement* init = NULL; | 2722 Statement* init = NULL; |
| 2708 | 2723 |
| 2709 Expect(Token::FOR, CHECK_OK); | 2724 Expect(Token::FOR, CHECK_OK); |
| 2710 Expect(Token::LPAREN, CHECK_OK); | 2725 Expect(Token::LPAREN, CHECK_OK); |
| 2711 if (peek() != Token::SEMICOLON) { | 2726 if (peek() != Token::SEMICOLON) { |
| 2712 if (peek() == Token::VAR || peek() == Token::CONST) { | 2727 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2713 Expression* each = NULL; | 2728 Expression* each = NULL; |
| 2714 Block* variable_statement = | 2729 Block* variable_statement = |
| 2715 ParseVariableDeclarations(false, &each, CHECK_OK); | 2730 ParseVariableDeclarations(false, &each, CHECK_OK); |
| 2716 if (peek() == Token::IN && each != NULL) { | 2731 if (peek() == Token::IN && each != NULL) { |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 NEW(FunctionLiteral(name, | 3963 NEW(FunctionLiteral(name, |
| 3949 top_scope_, | 3964 top_scope_, |
| 3950 body.elements(), | 3965 body.elements(), |
| 3951 materialized_literal_count, | 3966 materialized_literal_count, |
| 3952 expected_property_count, | 3967 expected_property_count, |
| 3953 only_simple_this_property_assignments, | 3968 only_simple_this_property_assignments, |
| 3954 this_property_assignments, | 3969 this_property_assignments, |
| 3955 num_parameters, | 3970 num_parameters, |
| 3956 start_pos, | 3971 start_pos, |
| 3957 end_pos, | 3972 end_pos, |
| 3958 function_name->length() > 0)); | 3973 function_name->length() > 0, |
| 3974 temp_scope.ContainsLoops())); |
| 3959 if (!is_pre_parsing_) { | 3975 if (!is_pre_parsing_) { |
| 3960 function_literal->set_function_token_position(function_token_position); | 3976 function_literal->set_function_token_position(function_token_position); |
| 3961 } | 3977 } |
| 3962 | 3978 |
| 3963 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3979 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3964 return function_literal; | 3980 return function_literal; |
| 3965 } | 3981 } |
| 3966 } | 3982 } |
| 3967 | 3983 |
| 3968 | 3984 |
| (...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5296 parser.ParseLazy(script_source, name, | 5312 parser.ParseLazy(script_source, name, |
| 5297 start_position, end_position, is_expression); | 5313 start_position, end_position, is_expression); |
| 5298 return result; | 5314 return result; |
| 5299 } | 5315 } |
| 5300 | 5316 |
| 5301 | 5317 |
| 5302 #undef NEW | 5318 #undef NEW |
| 5303 | 5319 |
| 5304 | 5320 |
| 5305 } } // namespace v8::internal | 5321 } } // namespace v8::internal |
| OLD | NEW |