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 |