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

Side by Side Diff: src/parser.cc

Issue 8462010: Add a level of indirection to exception handler addresses. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporate review changes. Created 9 years, 1 month 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
« no previous file with comments | « src/parser.h ('k') | src/v8globals.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/v8globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698