Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: src/parser.cc

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "ast.h" 31 #include "ast.h"
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "codegen.h"
33 #include "compiler.h" 34 #include "compiler.h"
34 #include "messages.h" 35 #include "messages.h"
35 #include "platform.h" 36 #include "platform.h"
36 #include "runtime.h" 37 #include "runtime.h"
37 #include "parser.h" 38 #include "parser.h"
38 #include "scopes.h" 39 #include "scopes.h"
39 #include "string-stream.h" 40 #include "string-stream.h"
40 41
41 namespace v8 { 42 namespace v8 {
42 namespace internal { 43 namespace internal {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 TemporaryScope* temp_scope_; 141 TemporaryScope* temp_scope_;
141 Mode mode_; 142 Mode mode_;
142 143
143 Target* target_stack_; // for break, continue statements 144 Target* target_stack_; // for break, continue statements
144 bool allow_natives_syntax_; 145 bool allow_natives_syntax_;
145 v8::Extension* extension_; 146 v8::Extension* extension_;
146 ParserFactory* factory_; 147 ParserFactory* factory_;
147 ParserLog* log_; 148 ParserLog* log_;
148 bool is_pre_parsing_; 149 bool is_pre_parsing_;
149 ScriptDataImpl* pre_data_; 150 ScriptDataImpl* pre_data_;
151 bool seen_loop_stmt_; // Used for inner loop detection.
150 152
151 bool inside_with() const { return with_nesting_level_ > 0; } 153 bool inside_with() const { return with_nesting_level_ > 0; }
152 ParserFactory* factory() const { return factory_; } 154 ParserFactory* factory() const { return factory_; }
153 ParserLog* log() const { return log_; } 155 ParserLog* log() const { return log_; }
154 Scanner& scanner() { return scanner_; } 156 Scanner& scanner() { return scanner_; }
155 Mode mode() const { return mode_; } 157 Mode mode() const { return mode_; }
156 ScriptDataImpl* pre_data() const { return pre_data_; } 158 ScriptDataImpl* pre_data() const { return pre_data_; }
157 159
158 // All ParseXXX functions take as the last argument an *ok parameter 160 // All ParseXXX functions take as the last argument an *ok parameter
159 // which is set to false if parsing failed; it is unchanged otherwise. 161 // which is set to false if parsing failed; it is unchanged otherwise.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 Expression* ParseArrayLiteral(bool* ok); 206 Expression* ParseArrayLiteral(bool* ok);
205 Expression* ParseObjectLiteral(bool* ok); 207 Expression* ParseObjectLiteral(bool* ok);
206 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); 208 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
207 209
208 // Populate the constant properties fixed array for a materialized object 210 // Populate the constant properties fixed array for a materialized object
209 // literal. 211 // literal.
210 void BuildObjectLiteralConstantProperties( 212 void BuildObjectLiteralConstantProperties(
211 ZoneList<ObjectLiteral::Property*>* properties, 213 ZoneList<ObjectLiteral::Property*>* properties,
212 Handle<FixedArray> constants, 214 Handle<FixedArray> constants,
213 bool* is_simple, 215 bool* is_simple,
216 bool* fast_elements,
214 int* depth); 217 int* depth);
215 218
216 // Populate the literals fixed array for a materialized array literal. 219 // Populate the literals fixed array for a materialized array literal.
217 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties, 220 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
218 Handle<FixedArray> constants, 221 Handle<FixedArray> constants,
219 bool* is_simple, 222 bool* is_simple,
220 int* depth); 223 int* depth);
221 224
222 // Decide if a property should be in the object boilerplate. 225 // Decide if a property should be in the object boilerplate.
223 bool IsBoilerplateProperty(ObjectLiteral::Property* property); 226 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 scanner_(is_pre_parsing), 1199 scanner_(is_pre_parsing),
1197 top_scope_(NULL), 1200 top_scope_(NULL),
1198 with_nesting_level_(0), 1201 with_nesting_level_(0),
1199 temp_scope_(NULL), 1202 temp_scope_(NULL),
1200 target_stack_(NULL), 1203 target_stack_(NULL),
1201 allow_natives_syntax_(allow_natives_syntax), 1204 allow_natives_syntax_(allow_natives_syntax),
1202 extension_(extension), 1205 extension_(extension),
1203 factory_(factory), 1206 factory_(factory),
1204 log_(log), 1207 log_(log),
1205 is_pre_parsing_(is_pre_parsing == PREPARSE), 1208 is_pre_parsing_(is_pre_parsing == PREPARSE),
1206 pre_data_(pre_data) { 1209 pre_data_(pre_data),
1210 seen_loop_stmt_(false) {
1207 } 1211 }
1208 1212
1209 1213
1210 bool Parser::PreParseProgram(Handle<String> source, 1214 bool Parser::PreParseProgram(Handle<String> source,
1211 unibrow::CharacterStream* stream) { 1215 unibrow::CharacterStream* stream) {
1212 HistogramTimerScope timer(&Counters::pre_parse); 1216 HistogramTimerScope timer(&Counters::pre_parse);
1213 AssertNoZoneAllocation assert_no_zone_allocation; 1217 AssertNoZoneAllocation assert_no_zone_allocation;
1214 AssertNoAllocation assert_no_allocation; 1218 AssertNoAllocation assert_no_allocation;
1215 NoHandleAllocation no_handle_allocation; 1219 NoHandleAllocation no_handle_allocation;
1216 scanner_.Initialize(source, stream, JAVASCRIPT); 1220 scanner_.Initialize(source, stream, JAVASCRIPT);
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 Property* property = assignment->target()->AsProperty(); 1580 Property* property = assignment->target()->AsProperty();
1577 return assignment->op() == Token::ASSIGN 1581 return assignment->op() == Token::ASSIGN
1578 && property != NULL 1582 && property != NULL
1579 && property->obj()->AsVariableProxy() != NULL 1583 && property->obj()->AsVariableProxy() != NULL
1580 && property->obj()->AsVariableProxy()->is_this(); 1584 && property->obj()->AsVariableProxy()->is_this();
1581 } 1585 }
1582 return false; 1586 return false;
1583 } 1587 }
1584 1588
1585 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) { 1589 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
1586 // Check that the property assigned to is a named property. 1590 // Check that the property assigned to is a named property, which is not
1591 // __proto__.
1587 Property* property = assignment->target()->AsProperty(); 1592 Property* property = assignment->target()->AsProperty();
1588 ASSERT(property != NULL); 1593 ASSERT(property != NULL);
1589 Literal* literal = property->key()->AsLiteral(); 1594 Literal* literal = property->key()->AsLiteral();
1590 uint32_t dummy; 1595 uint32_t dummy;
1591 if (literal != NULL && 1596 if (literal != NULL &&
1592 literal->handle()->IsString() && 1597 literal->handle()->IsString() &&
1598 !String::cast(*(literal->handle()))->Equals(Heap::Proto_symbol()) &&
1593 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { 1599 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1594 Handle<String> key = Handle<String>::cast(literal->handle()); 1600 Handle<String> key = Handle<String>::cast(literal->handle());
1595 1601
1596 // Check whether the value assigned is either a constant or matches the 1602 // Check whether the value assigned is either a constant or matches the
1597 // name of one of the arguments to the function. 1603 // name of one of the arguments to the function.
1598 if (assignment->value()->AsLiteral() != NULL) { 1604 if (assignment->value()->AsLiteral() != NULL) {
1599 // Constant assigned. 1605 // Constant assigned.
1600 Literal* literal = assignment->value()->AsLiteral(); 1606 Literal* literal = assignment->value()->AsLiteral();
1601 AssignmentFromConstant(key, literal->handle()); 1607 AssignmentFromConstant(key, literal->handle());
1602 return; 1608 return;
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 1961
1956 // Instantiate the function and create a boilerplate function from it. 1962 // Instantiate the function and create a boilerplate function from it.
1957 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 1963 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1958 const int literals = fun->NumberOfLiterals(); 1964 const int literals = fun->NumberOfLiterals();
1959 Handle<Code> code = Handle<Code>(fun->shared()->code()); 1965 Handle<Code> code = Handle<Code>(fun->shared()->code());
1960 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1966 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1961 Handle<JSFunction> boilerplate = 1967 Handle<JSFunction> boilerplate =
1962 Factory::NewFunctionBoilerplate(name, literals, code); 1968 Factory::NewFunctionBoilerplate(name, literals, code);
1963 boilerplate->shared()->set_construct_stub(*construct_stub); 1969 boilerplate->shared()->set_construct_stub(*construct_stub);
1964 1970
1965 // Copy the function data to the boilerplate. Used by 1971 // Copy the function data to the boilerplate.
1966 // builtins.cc:HandleApiCall to perform argument type checks and to
1967 // find the right native code to call.
1968 boilerplate->shared()->set_function_data(fun->shared()->function_data()); 1972 boilerplate->shared()->set_function_data(fun->shared()->function_data());
1969 int parameters = fun->shared()->formal_parameter_count(); 1973 int parameters = fun->shared()->formal_parameter_count();
1970 boilerplate->shared()->set_formal_parameter_count(parameters); 1974 boilerplate->shared()->set_formal_parameter_count(parameters);
1971 1975
1972 // TODO(1240846): It's weird that native function declarations are 1976 // TODO(1240846): It's weird that native function declarations are
1973 // introduced dynamically when we meet their declarations, whereas 1977 // introduced dynamically when we meet their declarations, whereas
1974 // other functions are setup when entering the surrounding scope. 1978 // other functions are setup when entering the surrounding scope.
1975 FunctionBoilerplateLiteral* lit = 1979 FunctionBoilerplateLiteral* lit =
1976 NEW(FunctionBoilerplateLiteral(boilerplate)); 1980 NEW(FunctionBoilerplateLiteral(boilerplate));
1977 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); 1981 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 Expression* cond = ParseExpression(true, CHECK_OK); 2648 Expression* cond = ParseExpression(true, CHECK_OK);
2645 Expect(Token::RPAREN, CHECK_OK); 2649 Expect(Token::RPAREN, CHECK_OK);
2646 2650
2647 // Allow do-statements to be terminated with and without 2651 // Allow do-statements to be terminated with and without
2648 // semi-colons. This allows code such as 'do;while(0)return' to 2652 // semi-colons. This allows code such as 'do;while(0)return' to
2649 // parse, which would not be the case if we had used the 2653 // parse, which would not be the case if we had used the
2650 // ExpectSemicolon() functionality here. 2654 // ExpectSemicolon() functionality here.
2651 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 2655 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2652 2656
2653 if (loop != NULL) loop->Initialize(cond, body); 2657 if (loop != NULL) loop->Initialize(cond, body);
2658
2659 seen_loop_stmt_ = true;
2660
2654 return loop; 2661 return loop;
2655 } 2662 }
2656 2663
2657 2664
2658 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 2665 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2659 // WhileStatement :: 2666 // WhileStatement ::
2660 // 'while' '(' Expression ')' Statement 2667 // 'while' '(' Expression ')' Statement
2661 2668
2662 WhileStatement* loop = NEW(WhileStatement(labels)); 2669 WhileStatement* loop = NEW(WhileStatement(labels));
2663 Target target(this, loop); 2670 Target target(this, loop);
2664 2671
2665 Expect(Token::WHILE, CHECK_OK); 2672 Expect(Token::WHILE, CHECK_OK);
2666 Expect(Token::LPAREN, CHECK_OK); 2673 Expect(Token::LPAREN, CHECK_OK);
2667 Expression* cond = ParseExpression(true, CHECK_OK); 2674 Expression* cond = ParseExpression(true, CHECK_OK);
2668 Expect(Token::RPAREN, CHECK_OK); 2675 Expect(Token::RPAREN, CHECK_OK);
2669 Statement* body = ParseStatement(NULL, CHECK_OK); 2676 Statement* body = ParseStatement(NULL, CHECK_OK);
2670 2677
2671 if (loop != NULL) loop->Initialize(cond, body); 2678 if (loop != NULL) loop->Initialize(cond, body);
2679
2680 seen_loop_stmt_ = true;
2681
2672 return loop; 2682 return loop;
2673 } 2683 }
2674 2684
2675 2685
2676 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2686 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2677 // ForStatement :: 2687 // ForStatement ::
2678 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2688 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2679 2689
2680 Statement* init = NULL; 2690 Statement* init = NULL;
2681 2691
(...skipping 13 matching lines...) Expand all
2695 Expect(Token::RPAREN, CHECK_OK); 2705 Expect(Token::RPAREN, CHECK_OK);
2696 2706
2697 Statement* body = ParseStatement(NULL, CHECK_OK); 2707 Statement* body = ParseStatement(NULL, CHECK_OK);
2698 if (is_pre_parsing_) { 2708 if (is_pre_parsing_) {
2699 return NULL; 2709 return NULL;
2700 } else { 2710 } else {
2701 loop->Initialize(each, enumerable, body); 2711 loop->Initialize(each, enumerable, body);
2702 Block* result = NEW(Block(NULL, 2, false)); 2712 Block* result = NEW(Block(NULL, 2, false));
2703 result->AddStatement(variable_statement); 2713 result->AddStatement(variable_statement);
2704 result->AddStatement(loop); 2714 result->AddStatement(loop);
2715
2716 seen_loop_stmt_ = true;
2717
2705 // Parsed for-in loop w/ variable/const declaration. 2718 // Parsed for-in loop w/ variable/const declaration.
2706 return result; 2719 return result;
2707 } 2720 }
2708 2721
2709 } else { 2722 } else {
2710 init = variable_statement; 2723 init = variable_statement;
2711 } 2724 }
2712 2725
2713 } else { 2726 } else {
2714 Expression* expression = ParseExpression(false, CHECK_OK); 2727 Expression* expression = ParseExpression(false, CHECK_OK);
2715 if (peek() == Token::IN) { 2728 if (peek() == Token::IN) {
2716 // Signal a reference error if the expression is an invalid 2729 // Signal a reference error if the expression is an invalid
2717 // left-hand side expression. We could report this as a syntax 2730 // left-hand side expression. We could report this as a syntax
2718 // error here but for compatibility with JSC we choose to report 2731 // error here but for compatibility with JSC we choose to report
2719 // the error at runtime. 2732 // the error at runtime.
2720 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2733 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2721 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); 2734 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol();
2722 expression = NewThrowReferenceError(type); 2735 expression = NewThrowReferenceError(type);
2723 } 2736 }
2724 ForInStatement* loop = NEW(ForInStatement(labels)); 2737 ForInStatement* loop = NEW(ForInStatement(labels));
2725 Target target(this, loop); 2738 Target target(this, loop);
2726 2739
2727 Expect(Token::IN, CHECK_OK); 2740 Expect(Token::IN, CHECK_OK);
2728 Expression* enumerable = ParseExpression(true, CHECK_OK); 2741 Expression* enumerable = ParseExpression(true, CHECK_OK);
2729 Expect(Token::RPAREN, CHECK_OK); 2742 Expect(Token::RPAREN, CHECK_OK);
2730 2743
2731 Statement* body = ParseStatement(NULL, CHECK_OK); 2744 Statement* body = ParseStatement(NULL, CHECK_OK);
2732 if (loop) loop->Initialize(expression, enumerable, body); 2745 if (loop) loop->Initialize(expression, enumerable, body);
2733 2746
2747 seen_loop_stmt_ = true;
2748
2734 // Parsed for-in loop. 2749 // Parsed for-in loop.
2735 return loop; 2750 return loop;
2736 2751
2737 } else { 2752 } else {
2738 init = NEW(ExpressionStatement(expression)); 2753 init = NEW(ExpressionStatement(expression));
2739 } 2754 }
2740 } 2755 }
2741 } 2756 }
2742 2757
2743 // Standard 'for' loop 2758 // Standard 'for' loop
(...skipping 12 matching lines...) Expand all
2756 } 2771 }
2757 Expect(Token::SEMICOLON, CHECK_OK); 2772 Expect(Token::SEMICOLON, CHECK_OK);
2758 2773
2759 Statement* next = NULL; 2774 Statement* next = NULL;
2760 if (peek() != Token::RPAREN) { 2775 if (peek() != Token::RPAREN) {
2761 Expression* exp = ParseExpression(true, CHECK_OK); 2776 Expression* exp = ParseExpression(true, CHECK_OK);
2762 next = NEW(ExpressionStatement(exp)); 2777 next = NEW(ExpressionStatement(exp));
2763 } 2778 }
2764 Expect(Token::RPAREN, CHECK_OK); 2779 Expect(Token::RPAREN, CHECK_OK);
2765 2780
2781 seen_loop_stmt_ = false;
2782
2766 Statement* body = ParseStatement(NULL, CHECK_OK); 2783 Statement* body = ParseStatement(NULL, CHECK_OK);
2767 2784
2785 // Mark this loop if it is an inner loop.
2786 if (loop && !seen_loop_stmt_) loop->set_peel_this_loop(true);
2787
2768 if (loop) loop->Initialize(init, cond, next, body); 2788 if (loop) loop->Initialize(init, cond, next, body);
2789
2790 seen_loop_stmt_ = true;
2791
2769 return loop; 2792 return loop;
2770 } 2793 }
2771 2794
2772 2795
2773 // Precedence = 1 2796 // Precedence = 1
2774 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { 2797 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2775 // Expression :: 2798 // Expression ::
2776 // AssignmentExpression 2799 // AssignmentExpression
2777 // Expression ',' AssignmentExpression 2800 // Expression ',' AssignmentExpression
2778 2801
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3461 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3439 return lit != NULL && lit->is_simple(); 3462 return lit != NULL && lit->is_simple();
3440 } 3463 }
3441 3464
3442 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { 3465 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3443 ASSERT(IsCompileTimeValue(expression)); 3466 ASSERT(IsCompileTimeValue(expression));
3444 Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED); 3467 Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED);
3445 ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3468 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3446 if (object_literal != NULL) { 3469 if (object_literal != NULL) {
3447 ASSERT(object_literal->is_simple()); 3470 ASSERT(object_literal->is_simple());
3448 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL)); 3471 if (object_literal->fast_elements()) {
3472 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3473 } else {
3474 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3475 }
3449 result->set(kElementsSlot, *object_literal->constant_properties()); 3476 result->set(kElementsSlot, *object_literal->constant_properties());
3450 } else { 3477 } else {
3451 ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3478 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3452 ASSERT(array_literal != NULL && array_literal->is_simple()); 3479 ASSERT(array_literal != NULL && array_literal->is_simple());
3453 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 3480 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3454 result->set(kElementsSlot, *array_literal->constant_elements()); 3481 result->set(kElementsSlot, *array_literal->constant_elements());
3455 } 3482 }
3456 return result; 3483 return result;
3457 } 3484 }
3458 3485
(...skipping 17 matching lines...) Expand all
3476 return CompileTimeValue::GetValue(expression); 3503 return CompileTimeValue::GetValue(expression);
3477 } 3504 }
3478 return Factory::undefined_value(); 3505 return Factory::undefined_value();
3479 } 3506 }
3480 3507
3481 3508
3482 void Parser::BuildObjectLiteralConstantProperties( 3509 void Parser::BuildObjectLiteralConstantProperties(
3483 ZoneList<ObjectLiteral::Property*>* properties, 3510 ZoneList<ObjectLiteral::Property*>* properties,
3484 Handle<FixedArray> constant_properties, 3511 Handle<FixedArray> constant_properties,
3485 bool* is_simple, 3512 bool* is_simple,
3513 bool* fast_elements,
3486 int* depth) { 3514 int* depth) {
3487 int position = 0; 3515 int position = 0;
3488 // Accumulate the value in local variables and store it at the end. 3516 // Accumulate the value in local variables and store it at the end.
3489 bool is_simple_acc = true; 3517 bool is_simple_acc = true;
3490 int depth_acc = 1; 3518 int depth_acc = 1;
3519 uint32_t max_element_index = 0;
3520 uint32_t elements = 0;
3491 for (int i = 0; i < properties->length(); i++) { 3521 for (int i = 0; i < properties->length(); i++) {
3492 ObjectLiteral::Property* property = properties->at(i); 3522 ObjectLiteral::Property* property = properties->at(i);
3493 if (!IsBoilerplateProperty(property)) { 3523 if (!IsBoilerplateProperty(property)) {
3494 is_simple_acc = false; 3524 is_simple_acc = false;
3495 continue; 3525 continue;
3496 } 3526 }
3497 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 3527 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3498 if (m_literal != NULL && m_literal->depth() >= depth_acc) { 3528 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3499 depth_acc = m_literal->depth() + 1; 3529 depth_acc = m_literal->depth() + 1;
3500 } 3530 }
3501 3531
3502 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined 3532 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3503 // value for COMPUTED properties, the real value is filled in at 3533 // value for COMPUTED properties, the real value is filled in at
3504 // runtime. The enumeration order is maintained. 3534 // runtime. The enumeration order is maintained.
3505 Handle<Object> key = property->key()->handle(); 3535 Handle<Object> key = property->key()->handle();
3506 Handle<Object> value = GetBoilerplateValue(property->value()); 3536 Handle<Object> value = GetBoilerplateValue(property->value());
3507 is_simple_acc = is_simple_acc && !value->IsUndefined(); 3537 is_simple_acc = is_simple_acc && !value->IsUndefined();
3508 3538
3539 // Keep track of the number of elements in the object literal and
3540 // the largest element index. If the largest element index is
3541 // much larger than the number of elements, creating an object
3542 // literal with fast elements will be a waste of space.
3543 uint32_t element_index = 0;
3544 if (key->IsString()
3545 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
3546 && element_index > max_element_index) {
3547 max_element_index = element_index;
3548 elements++;
3549 } else if (key->IsSmi()) {
3550 int key_value = Smi::cast(*key)->value();
3551 if (key_value > 0
3552 && static_cast<uint32_t>(key_value) > max_element_index) {
3553 max_element_index = key_value;
3554 }
3555 elements++;
3556 }
3557
3509 // Add name, value pair to the fixed array. 3558 // Add name, value pair to the fixed array.
3510 constant_properties->set(position++, *key); 3559 constant_properties->set(position++, *key);
3511 constant_properties->set(position++, *value); 3560 constant_properties->set(position++, *value);
3512 } 3561 }
3513 3562 *fast_elements =
3563 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
3514 *is_simple = is_simple_acc; 3564 *is_simple = is_simple_acc;
3515 *depth = depth_acc; 3565 *depth = depth_acc;
3516 } 3566 }
3517 3567
3518 3568
3519 Expression* Parser::ParseObjectLiteral(bool* ok) { 3569 Expression* Parser::ParseObjectLiteral(bool* ok) {
3520 // ObjectLiteral :: 3570 // ObjectLiteral ::
3521 // '{' ( 3571 // '{' (
3522 // ((Identifier | String | Number) ':' AssignmentExpression) 3572 // ((Identifier | String | Number) ':' AssignmentExpression)
3523 // | (('get' | 'set') FunctionLiteral) 3573 // | (('get' | 'set') FunctionLiteral)
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3601 } 3651 }
3602 Expect(Token::RBRACE, CHECK_OK); 3652 Expect(Token::RBRACE, CHECK_OK);
3603 // Computation of literal_index must happen before pre parse bailout. 3653 // Computation of literal_index must happen before pre parse bailout.
3604 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3654 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3605 if (is_pre_parsing_) return NULL; 3655 if (is_pre_parsing_) return NULL;
3606 3656
3607 Handle<FixedArray> constant_properties = 3657 Handle<FixedArray> constant_properties =
3608 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); 3658 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
3609 3659
3610 bool is_simple = true; 3660 bool is_simple = true;
3661 bool fast_elements = true;
3611 int depth = 1; 3662 int depth = 1;
3612 BuildObjectLiteralConstantProperties(properties.elements(), 3663 BuildObjectLiteralConstantProperties(properties.elements(),
3613 constant_properties, 3664 constant_properties,
3614 &is_simple, 3665 &is_simple,
3666 &fast_elements,
3615 &depth); 3667 &depth);
3616 return new ObjectLiteral(constant_properties, 3668 return new ObjectLiteral(constant_properties,
3617 properties.elements(), 3669 properties.elements(),
3618 literal_index, 3670 literal_index,
3619 is_simple, 3671 is_simple,
3672 fast_elements,
3620 depth); 3673 depth);
3621 } 3674 }
3622 3675
3623 3676
3624 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3677 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3625 if (!scanner_.ScanRegExpPattern(seen_equal)) { 3678 if (!scanner_.ScanRegExpPattern(seen_equal)) {
3626 Next(); 3679 Next();
3627 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 3680 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3628 *ok = false; 3681 *ok = false;
3629 return NULL; 3682 return NULL;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3673 } 3726 }
3674 3727
3675 3728
3676 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3729 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3677 int function_token_position, 3730 int function_token_position,
3678 FunctionLiteralType type, 3731 FunctionLiteralType type,
3679 bool* ok) { 3732 bool* ok) {
3680 // Function :: 3733 // Function ::
3681 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3734 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3682 3735
3736 // Reset flag used for inner loop detection.
3737 seen_loop_stmt_ = false;
3738
3683 bool is_named = !var_name.is_null(); 3739 bool is_named = !var_name.is_null();
3684 3740
3685 // The name associated with this function. If it's a function expression, 3741 // The name associated with this function. If it's a function expression,
3686 // this is the actual function name, otherwise this is the name of the 3742 // this is the actual function name, otherwise this is the name of the
3687 // variable declared and initialized with the function (expression). In 3743 // variable declared and initialized with the function (expression). In
3688 // that case, we don't have a function name (it's empty). 3744 // that case, we don't have a function name (it's empty).
3689 Handle<String> name = is_named ? var_name : factory()->EmptySymbol(); 3745 Handle<String> name = is_named ? var_name : factory()->EmptySymbol();
3690 // The function name, if any. 3746 // The function name, if any.
3691 Handle<String> function_name = factory()->EmptySymbol(); 3747 Handle<String> function_name = factory()->EmptySymbol();
3692 if (is_named && (type == EXPRESSION || type == NESTED)) { 3748 if (is_named && (type == EXPRESSION || type == NESTED)) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3783 expected_property_count, 3839 expected_property_count,
3784 only_simple_this_property_assignments, 3840 only_simple_this_property_assignments,
3785 this_property_assignments, 3841 this_property_assignments,
3786 num_parameters, 3842 num_parameters,
3787 start_pos, 3843 start_pos,
3788 end_pos, 3844 end_pos,
3789 function_name->length() > 0)); 3845 function_name->length() > 0));
3790 if (!is_pre_parsing_) { 3846 if (!is_pre_parsing_) {
3791 function_literal->set_function_token_position(function_token_position); 3847 function_literal->set_function_token_position(function_token_position);
3792 } 3848 }
3849
3850 // Set flag for inner loop detection. We treat loops that contain a function
3851 // literal not as inner loops because we avoid duplicating function literals
3852 // when peeling or unrolling such a loop.
3853 seen_loop_stmt_ = true;
3854
3793 return function_literal; 3855 return function_literal;
3794 } 3856 }
3795 } 3857 }
3796 3858
3797 3859
3798 Expression* Parser::ParseV8Intrinsic(bool* ok) { 3860 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3799 // CallRuntime :: 3861 // CallRuntime ::
3800 // '%' Identifier Arguments 3862 // '%' Identifier Arguments
3801 3863
3802 Expect(Token::MOD, CHECK_OK); 3864 Expect(Token::MOD, CHECK_OK);
(...skipping 22 matching lines...) Expand all
3825 // ... 3887 // ...
3826 } 3888 }
3827 3889
3828 if (!*ok) { 3890 if (!*ok) {
3829 // We found a macro but it failed. 3891 // We found a macro but it failed.
3830 ReportMessage("unable_to_parse", Vector<const char*>::empty()); 3892 ReportMessage("unable_to_parse", Vector<const char*>::empty());
3831 return NULL; 3893 return NULL;
3832 } 3894 }
3833 } 3895 }
3834 3896
3835 // Otherwise we have a runtime call. 3897 // Check that the expected number arguments are passed to runtime functions.
3898 if (!is_pre_parsing_) {
3899 if (function != NULL
3900 && function->nargs != -1
3901 && function->nargs != args->length()) {
3902 ReportMessage("illegal_access", Vector<const char*>::empty());
3903 *ok = false;
3904 return NULL;
3905 } else if (function == NULL && !name.is_null()) {
3906 // If this is not a runtime function implemented in C++ it might be an
3907 // inlined runtime function.
3908 int argc = CodeGenerator::InlineRuntimeCallArgumentsCount(name);
3909 if (argc != -1 && argc != args->length()) {
3910 ReportMessage("illegal_access", Vector<const char*>::empty());
3911 *ok = false;
3912 return NULL;
3913 }
3914 }
3915 }
3916
3917 // Otherwise we have a valid runtime call.
3836 return NEW(CallRuntime(name, function, args)); 3918 return NEW(CallRuntime(name, function, args));
3837 } 3919 }
3838 3920
3839 3921
3840 void Parser::Consume(Token::Value token) { 3922 void Parser::Consume(Token::Value token) {
3841 Token::Value next = Next(); 3923 Token::Value next = Next();
3842 USE(next); 3924 USE(next);
3843 USE(token); 3925 USE(token);
3844 ASSERT(next == token); 3926 ASSERT(next == token);
3845 } 3927 }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
4116 } while (Check(Token::COMMA)); 4198 } while (Check(Token::COMMA));
4117 } 4199 }
4118 Expect(Token::RBRACE, CHECK_OK); 4200 Expect(Token::RBRACE, CHECK_OK);
4119 4201
4120 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 4202 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
4121 if (is_pre_parsing_) return NULL; 4203 if (is_pre_parsing_) return NULL;
4122 4204
4123 Handle<FixedArray> constant_properties = 4205 Handle<FixedArray> constant_properties =
4124 Factory::NewFixedArray(boilerplate_properties * 2, TENURED); 4206 Factory::NewFixedArray(boilerplate_properties * 2, TENURED);
4125 bool is_simple = true; 4207 bool is_simple = true;
4208 bool fast_elements = true;
4126 int depth = 1; 4209 int depth = 1;
4127 BuildObjectLiteralConstantProperties(properties.elements(), 4210 BuildObjectLiteralConstantProperties(properties.elements(),
4128 constant_properties, 4211 constant_properties,
4129 &is_simple, 4212 &is_simple,
4213 &fast_elements,
4130 &depth); 4214 &depth);
4131 return new ObjectLiteral(constant_properties, 4215 return new ObjectLiteral(constant_properties,
4132 properties.elements(), 4216 properties.elements(),
4133 literal_index, 4217 literal_index,
4134 is_simple, 4218 is_simple,
4219 fast_elements,
4135 depth); 4220 depth);
4136 } 4221 }
4137 4222
4138 4223
4139 // Parse a JSON array. Scanner must be right after '[' token. 4224 // Parse a JSON array. Scanner must be right after '[' token.
4140 Expression* Parser::ParseJsonArray(bool* ok) { 4225 Expression* Parser::ParseJsonArray(bool* ok) {
4141 Consume(Token::LBRACK); 4226 Consume(Token::LBRACK);
4142 4227
4143 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); 4228 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4);
4144 if (peek() != Token::RBRACK) { 4229 if (peek() != Token::RBRACK) {
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
5089 parser.ParseLazy(script_source, name, 5174 parser.ParseLazy(script_source, name,
5090 start_position, end_position, is_expression); 5175 start_position, end_position, is_expression);
5091 return result; 5176 return result;
5092 } 5177 }
5093 5178
5094 5179
5095 #undef NEW 5180 #undef NEW
5096 5181
5097 5182
5098 } } // namespace v8::internal 5183 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698