OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 FunctionState(Parser* parser, Scope* scope, Isolate* isolate); | 486 FunctionState(Parser* parser, Scope* scope, Isolate* isolate); |
487 ~FunctionState(); | 487 ~FunctionState(); |
488 | 488 |
489 int NextMaterializedLiteralIndex() { | 489 int NextMaterializedLiteralIndex() { |
490 return next_materialized_literal_index_++; | 490 return next_materialized_literal_index_++; |
491 } | 491 } |
492 int materialized_literal_count() { | 492 int materialized_literal_count() { |
493 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 493 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
494 } | 494 } |
495 | 495 |
| 496 int NextHandlerIndex() { return next_handler_index_++; } |
| 497 int handler_count() { return next_handler_index_; } |
| 498 |
496 void SetThisPropertyAssignmentInfo( | 499 void SetThisPropertyAssignmentInfo( |
497 bool only_simple_this_property_assignments, | 500 bool only_simple_this_property_assignments, |
498 Handle<FixedArray> this_property_assignments) { | 501 Handle<FixedArray> this_property_assignments) { |
499 only_simple_this_property_assignments_ = | 502 only_simple_this_property_assignments_ = |
500 only_simple_this_property_assignments; | 503 only_simple_this_property_assignments; |
501 this_property_assignments_ = this_property_assignments; | 504 this_property_assignments_ = this_property_assignments; |
502 } | 505 } |
503 bool only_simple_this_property_assignments() { | 506 bool only_simple_this_property_assignments() { |
504 return only_simple_this_property_assignments_; | 507 return only_simple_this_property_assignments_; |
505 } | 508 } |
506 Handle<FixedArray> this_property_assignments() { | 509 Handle<FixedArray> this_property_assignments() { |
507 return this_property_assignments_; | 510 return this_property_assignments_; |
508 } | 511 } |
509 | 512 |
510 void AddProperty() { expected_property_count_++; } | 513 void AddProperty() { expected_property_count_++; } |
511 int expected_property_count() { return expected_property_count_; } | 514 int expected_property_count() { return expected_property_count_; } |
512 | 515 |
513 private: | 516 private: |
514 // Used to assign an index to each literal that needs materialization in | 517 // Used to assign an index to each literal that needs materialization in |
515 // the function. Includes regexp literals, and boilerplate for object and | 518 // the function. Includes regexp literals, and boilerplate for object and |
516 // array literals. | 519 // array literals. |
517 int next_materialized_literal_index_; | 520 int next_materialized_literal_index_; |
518 | 521 |
| 522 // Used to assign a per-function index to try and catch handlers. |
| 523 int next_handler_index_; |
| 524 |
519 // Properties count estimation. | 525 // Properties count estimation. |
520 int expected_property_count_; | 526 int expected_property_count_; |
521 | 527 |
522 // Keeps track of assignments to properties of this. Used for | 528 // Keeps track of assignments to properties of this. Used for |
523 // optimizing constructors. | 529 // optimizing constructors. |
524 bool only_simple_this_property_assignments_; | 530 bool only_simple_this_property_assignments_; |
525 Handle<FixedArray> this_property_assignments_; | 531 Handle<FixedArray> this_property_assignments_; |
526 | 532 |
527 Parser* parser_; | 533 Parser* parser_; |
528 FunctionState* outer_function_state_; | 534 FunctionState* outer_function_state_; |
529 Scope* outer_scope_; | 535 Scope* outer_scope_; |
530 unsigned saved_ast_node_id_; | 536 unsigned saved_ast_node_id_; |
531 }; | 537 }; |
532 | 538 |
533 | 539 |
534 Parser::FunctionState::FunctionState(Parser* parser, | 540 Parser::FunctionState::FunctionState(Parser* parser, |
535 Scope* scope, | 541 Scope* scope, |
536 Isolate* isolate) | 542 Isolate* isolate) |
537 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 543 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 544 next_handler_index_(0), |
538 expected_property_count_(0), | 545 expected_property_count_(0), |
539 only_simple_this_property_assignments_(false), | 546 only_simple_this_property_assignments_(false), |
540 this_property_assignments_(isolate->factory()->empty_fixed_array()), | 547 this_property_assignments_(isolate->factory()->empty_fixed_array()), |
541 parser_(parser), | 548 parser_(parser), |
542 outer_function_state_(parser->current_function_state_), | 549 outer_function_state_(parser->current_function_state_), |
543 outer_scope_(parser->top_scope_), | 550 outer_scope_(parser->top_scope_), |
544 saved_ast_node_id_(isolate->ast_node_id()) { | 551 saved_ast_node_id_(isolate->ast_node_id()) { |
545 parser->top_scope_ = scope; | 552 parser->top_scope_ = scope; |
546 parser->current_function_state_ = this; | 553 parser->current_function_state_ = this; |
547 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); | 554 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 bool allow_natives_syntax, | 589 bool allow_natives_syntax, |
583 v8::Extension* extension, | 590 v8::Extension* extension, |
584 ScriptDataImpl* pre_data) | 591 ScriptDataImpl* pre_data) |
585 : isolate_(script->GetIsolate()), | 592 : isolate_(script->GetIsolate()), |
586 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), | 593 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
587 script_(script), | 594 script_(script), |
588 scanner_(isolate_->unicode_cache()), | 595 scanner_(isolate_->unicode_cache()), |
589 top_scope_(NULL), | 596 top_scope_(NULL), |
590 current_function_state_(NULL), | 597 current_function_state_(NULL), |
591 target_stack_(NULL), | 598 target_stack_(NULL), |
592 allow_natives_syntax_(allow_natives_syntax), | |
593 extension_(extension), | 599 extension_(extension), |
594 pre_data_(pre_data), | 600 pre_data_(pre_data), |
595 fni_(NULL), | 601 fni_(NULL), |
| 602 allow_natives_syntax_(allow_natives_syntax), |
596 stack_overflow_(false), | 603 stack_overflow_(false), |
597 parenthesized_function_(false), | 604 parenthesized_function_(false), |
598 harmony_scoping_(false) { | 605 harmony_scoping_(false) { |
599 AstNode::ResetIds(); | 606 AstNode::ResetIds(); |
600 } | 607 } |
601 | 608 |
602 | 609 |
603 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 610 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
604 bool in_global_context, | 611 bool in_global_context, |
605 StrictModeFlag strict_mode) { | 612 StrictModeFlag strict_mode) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 } | 669 } |
663 | 670 |
664 if (ok) { | 671 if (ok) { |
665 result = new(zone()) FunctionLiteral( | 672 result = new(zone()) FunctionLiteral( |
666 isolate(), | 673 isolate(), |
667 no_name, | 674 no_name, |
668 top_scope_, | 675 top_scope_, |
669 body, | 676 body, |
670 function_state.materialized_literal_count(), | 677 function_state.materialized_literal_count(), |
671 function_state.expected_property_count(), | 678 function_state.expected_property_count(), |
| 679 function_state.handler_count(), |
672 function_state.only_simple_this_property_assignments(), | 680 function_state.only_simple_this_property_assignments(), |
673 function_state.this_property_assignments(), | 681 function_state.this_property_assignments(), |
674 0, | 682 0, |
675 FunctionLiteral::ANONYMOUS_EXPRESSION, | 683 FunctionLiteral::ANONYMOUS_EXPRESSION, |
676 false); // Does not have duplicate parameters. | 684 false); // Does not have duplicate parameters. |
677 } else if (stack_overflow_) { | 685 } else if (stack_overflow_) { |
678 isolate()->StackOverflow(); | 686 isolate()->StackOverflow(); |
679 } | 687 } |
680 } | 688 } |
681 | 689 |
(...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2309 } | 2317 } |
2310 | 2318 |
2311 // Simplify the AST nodes by converting: | 2319 // Simplify the AST nodes by converting: |
2312 // 'try B0 catch B1 finally B2' | 2320 // 'try B0 catch B1 finally B2' |
2313 // to: | 2321 // to: |
2314 // 'try { try B0 catch B1 } finally B2' | 2322 // 'try { try B0 catch B1 } finally B2' |
2315 | 2323 |
2316 if (catch_block != NULL && finally_block != NULL) { | 2324 if (catch_block != NULL && finally_block != NULL) { |
2317 // If we have both, create an inner try/catch. | 2325 // If we have both, create an inner try/catch. |
2318 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2326 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2319 TryCatchStatement* statement = | 2327 int index = current_function_state_->NextHandlerIndex(); |
2320 new(zone()) TryCatchStatement(try_block, | 2328 TryCatchStatement* statement = new(zone()) TryCatchStatement(index, |
2321 catch_scope, | 2329 try_block, |
2322 catch_variable, | 2330 catch_scope, |
2323 catch_block); | 2331 catch_variable, |
| 2332 catch_block); |
2324 statement->set_escaping_targets(try_collector.targets()); | 2333 statement->set_escaping_targets(try_collector.targets()); |
2325 try_block = new(zone()) Block(isolate(), NULL, 1, false); | 2334 try_block = new(zone()) Block(isolate(), NULL, 1, false); |
2326 try_block->AddStatement(statement); | 2335 try_block->AddStatement(statement); |
2327 catch_block = NULL; // Clear to indicate it's been handled. | 2336 catch_block = NULL; // Clear to indicate it's been handled. |
2328 } | 2337 } |
2329 | 2338 |
2330 TryStatement* result = NULL; | 2339 TryStatement* result = NULL; |
2331 if (catch_block != NULL) { | 2340 if (catch_block != NULL) { |
2332 ASSERT(finally_block == NULL); | 2341 ASSERT(finally_block == NULL); |
2333 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2342 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2334 result = | 2343 int index = current_function_state_->NextHandlerIndex(); |
2335 new(zone()) TryCatchStatement(try_block, | 2344 result = new(zone()) TryCatchStatement(index, |
2336 catch_scope, | 2345 try_block, |
2337 catch_variable, | 2346 catch_scope, |
2338 catch_block); | 2347 catch_variable, |
| 2348 catch_block); |
2339 } else { | 2349 } else { |
2340 ASSERT(finally_block != NULL); | 2350 ASSERT(finally_block != NULL); |
2341 result = new(zone()) TryFinallyStatement(try_block, finally_block); | 2351 int index = current_function_state_->NextHandlerIndex(); |
| 2352 result = new(zone()) TryFinallyStatement(index, |
| 2353 try_block, |
| 2354 finally_block); |
2342 // Combine the jump targets of the try block and the possible catch block. | 2355 // Combine the jump targets of the try block and the possible catch block. |
2343 try_collector.targets()->AddAll(*catch_collector.targets()); | 2356 try_collector.targets()->AddAll(*catch_collector.targets()); |
2344 } | 2357 } |
2345 | 2358 |
2346 result->set_escaping_targets(try_collector.targets()); | 2359 result->set_escaping_targets(try_collector.targets()); |
2347 return result; | 2360 return result; |
2348 } | 2361 } |
2349 | 2362 |
2350 | 2363 |
2351 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2364 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3890 function_name = isolate()->factory()->empty_symbol(); | 3903 function_name = isolate()->factory()->empty_symbol(); |
3891 } | 3904 } |
3892 | 3905 |
3893 int num_parameters = 0; | 3906 int num_parameters = 0; |
3894 // Function declarations are function scoped in normal mode, so they are | 3907 // Function declarations are function scoped in normal mode, so they are |
3895 // hoisted. In harmony block scoping mode they are block scoped, so they | 3908 // hoisted. In harmony block scoping mode they are block scoped, so they |
3896 // are not hoisted. | 3909 // are not hoisted. |
3897 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) | 3910 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) |
3898 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) | 3911 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) |
3899 : NewScope(top_scope_, FUNCTION_SCOPE); | 3912 : NewScope(top_scope_, FUNCTION_SCOPE); |
3900 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3913 ZoneList<Statement*>* body = NULL; |
3901 int materialized_literal_count; | 3914 int materialized_literal_count; |
3902 int expected_property_count; | 3915 int expected_property_count; |
| 3916 int handler_count = 0; |
3903 bool only_simple_this_property_assignments; | 3917 bool only_simple_this_property_assignments; |
3904 Handle<FixedArray> this_property_assignments; | 3918 Handle<FixedArray> this_property_assignments; |
3905 bool has_duplicate_parameters = false; | 3919 bool has_duplicate_parameters = false; |
3906 // Parse function body. | 3920 // Parse function body. |
3907 { FunctionState function_state(this, scope, isolate()); | 3921 { FunctionState function_state(this, scope, isolate()); |
3908 top_scope_->SetScopeName(function_name); | 3922 top_scope_->SetScopeName(function_name); |
3909 | 3923 |
3910 // FormalParameterList :: | 3924 // FormalParameterList :: |
3911 // '(' (Identifier)*[','] ')' | 3925 // '(' (Identifier)*[','] ')' |
3912 Expect(Token::LPAREN, CHECK_OK); | 3926 Expect(Token::LPAREN, CHECK_OK); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3948 Expect(Token::RPAREN, CHECK_OK); | 3962 Expect(Token::RPAREN, CHECK_OK); |
3949 | 3963 |
3950 Expect(Token::LBRACE, CHECK_OK); | 3964 Expect(Token::LBRACE, CHECK_OK); |
3951 | 3965 |
3952 // If we have a named function expression, we add a local variable | 3966 // If we have a named function expression, we add a local variable |
3953 // declaration to the body of the function with the name of the | 3967 // declaration to the body of the function with the name of the |
3954 // function and let it refer to the function itself (closure). | 3968 // function and let it refer to the function itself (closure). |
3955 // NOTE: We create a proxy and resolve it here so that in the | 3969 // NOTE: We create a proxy and resolve it here so that in the |
3956 // future we can change the AST to only refer to VariableProxies | 3970 // future we can change the AST to only refer to VariableProxies |
3957 // instead of Variables and Proxis as is the case now. | 3971 // instead of Variables and Proxis as is the case now. |
| 3972 Variable* fvar = NULL; |
| 3973 Token::Value fvar_init_op = Token::INIT_CONST; |
3958 if (type == FunctionLiteral::NAMED_EXPRESSION) { | 3974 if (type == FunctionLiteral::NAMED_EXPRESSION) { |
3959 VariableMode fvar_mode; | 3975 VariableMode fvar_mode; |
3960 Token::Value fvar_init_op; | |
3961 if (harmony_scoping_) { | 3976 if (harmony_scoping_) { |
3962 fvar_mode = CONST_HARMONY; | 3977 fvar_mode = CONST_HARMONY; |
3963 fvar_init_op = Token::INIT_CONST_HARMONY; | 3978 fvar_init_op = Token::INIT_CONST_HARMONY; |
3964 } else { | 3979 } else { |
3965 fvar_mode = CONST; | 3980 fvar_mode = CONST; |
3966 fvar_init_op = Token::INIT_CONST; | |
3967 } | 3981 } |
3968 Variable* fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); | 3982 fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); |
3969 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); | |
3970 fproxy->BindTo(fvar); | |
3971 body->Add(new(zone()) ExpressionStatement( | |
3972 new(zone()) Assignment(isolate(), | |
3973 fvar_init_op, | |
3974 fproxy, | |
3975 new(zone()) ThisFunction(isolate()), | |
3976 RelocInfo::kNoPosition))); | |
3977 } | 3983 } |
3978 | 3984 |
3979 // Determine if the function will be lazily compiled. The mode can only | 3985 // Determine if the function will be lazily compiled. The mode can only |
3980 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily | 3986 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily |
3981 // compile if we do not have preparser data for the function. | 3987 // compile if we do not have preparser data for the function. |
3982 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 3988 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
3983 top_scope_->outer_scope()->is_global_scope() && | 3989 top_scope_->outer_scope()->is_global_scope() && |
3984 top_scope_->HasTrivialOuterContext() && | 3990 top_scope_->HasTrivialOuterContext() && |
3985 !parenthesized_function_ && | 3991 !parenthesized_function_ && |
3986 pre_data() != NULL); | 3992 pre_data() != NULL); |
(...skipping 19 matching lines...) Expand all Loading... |
4006 materialized_literal_count = entry.literal_count(); | 4012 materialized_literal_count = entry.literal_count(); |
4007 expected_property_count = entry.property_count(); | 4013 expected_property_count = entry.property_count(); |
4008 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); | 4014 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); |
4009 only_simple_this_property_assignments = false; | 4015 only_simple_this_property_assignments = false; |
4010 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 4016 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
4011 Expect(Token::RBRACE, CHECK_OK); | 4017 Expect(Token::RBRACE, CHECK_OK); |
4012 } | 4018 } |
4013 } | 4019 } |
4014 | 4020 |
4015 if (!is_lazily_compiled) { | 4021 if (!is_lazily_compiled) { |
| 4022 body = new(zone()) ZoneList<Statement*>(8); |
| 4023 if (fvar != NULL) { |
| 4024 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); |
| 4025 fproxy->BindTo(fvar); |
| 4026 body->Add(new(zone()) ExpressionStatement( |
| 4027 new(zone()) Assignment(isolate(), |
| 4028 fvar_init_op, |
| 4029 fproxy, |
| 4030 new(zone()) ThisFunction(isolate()), |
| 4031 RelocInfo::kNoPosition))); |
| 4032 } |
4016 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 4033 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
4017 | 4034 |
4018 materialized_literal_count = function_state.materialized_literal_count(); | 4035 materialized_literal_count = function_state.materialized_literal_count(); |
4019 expected_property_count = function_state.expected_property_count(); | 4036 expected_property_count = function_state.expected_property_count(); |
| 4037 handler_count = function_state.handler_count(); |
4020 only_simple_this_property_assignments = | 4038 only_simple_this_property_assignments = |
4021 function_state.only_simple_this_property_assignments(); | 4039 function_state.only_simple_this_property_assignments(); |
4022 this_property_assignments = function_state.this_property_assignments(); | 4040 this_property_assignments = function_state.this_property_assignments(); |
4023 | 4041 |
4024 Expect(Token::RBRACE, CHECK_OK); | 4042 Expect(Token::RBRACE, CHECK_OK); |
4025 scope->set_end_position(scanner().location().end_pos); | 4043 scope->set_end_position(scanner().location().end_pos); |
4026 } | 4044 } |
4027 | 4045 |
4028 // Validate strict mode. | 4046 // Validate strict mode. |
4029 if (top_scope_->is_strict_mode()) { | 4047 if (top_scope_->is_strict_mode()) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4077 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4095 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4078 } | 4096 } |
4079 | 4097 |
4080 FunctionLiteral* function_literal = | 4098 FunctionLiteral* function_literal = |
4081 new(zone()) FunctionLiteral(isolate(), | 4099 new(zone()) FunctionLiteral(isolate(), |
4082 function_name, | 4100 function_name, |
4083 scope, | 4101 scope, |
4084 body, | 4102 body, |
4085 materialized_literal_count, | 4103 materialized_literal_count, |
4086 expected_property_count, | 4104 expected_property_count, |
| 4105 handler_count, |
4087 only_simple_this_property_assignments, | 4106 only_simple_this_property_assignments, |
4088 this_property_assignments, | 4107 this_property_assignments, |
4089 num_parameters, | 4108 num_parameters, |
4090 type, | 4109 type, |
4091 has_duplicate_parameters); | 4110 has_duplicate_parameters); |
4092 function_literal->set_function_token_position(function_token_position); | 4111 function_literal->set_function_token_position(function_token_position); |
4093 | 4112 |
4094 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4113 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
4095 return function_literal; | 4114 return function_literal; |
4096 } | 4115 } |
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5418 result = parser.ParseProgram(source, | 5437 result = parser.ParseProgram(source, |
5419 info->is_global(), | 5438 info->is_global(), |
5420 info->strict_mode_flag()); | 5439 info->strict_mode_flag()); |
5421 } | 5440 } |
5422 } | 5441 } |
5423 info->SetFunction(result); | 5442 info->SetFunction(result); |
5424 return (result != NULL); | 5443 return (result != NULL); |
5425 } | 5444 } |
5426 | 5445 |
5427 } } // namespace v8::internal | 5446 } } // namespace v8::internal |
OLD | NEW |