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