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

Side by Side Diff: src/parser.cc

Issue 8662037: Don't preparse large files to find boundaries of lazy functions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years 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/preparser.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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 #define CHECK_FAILED /**/); \ 579 #define CHECK_FAILED /**/); \
580 if (failed_) return NULL; \ 580 if (failed_) return NULL; \
581 ((void)0 581 ((void)0
582 #define DUMMY ) // to make indentation work 582 #define DUMMY ) // to make indentation work
583 #undef DUMMY 583 #undef DUMMY
584 584
585 // ---------------------------------------------------------------------------- 585 // ----------------------------------------------------------------------------
586 // Implementation of Parser 586 // Implementation of Parser
587 587
588 Parser::Parser(Handle<Script> script, 588 Parser::Parser(Handle<Script> script,
589 bool allow_natives_syntax, 589 int parser_flags,
590 v8::Extension* extension, 590 v8::Extension* extension,
591 ScriptDataImpl* pre_data) 591 ScriptDataImpl* pre_data)
592 : isolate_(script->GetIsolate()), 592 : isolate_(script->GetIsolate()),
593 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), 593 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
594 script_(script), 594 script_(script),
595 scanner_(isolate_->unicode_cache()), 595 scanner_(isolate_->unicode_cache()),
596 reusable_preparser_(NULL),
596 top_scope_(NULL), 597 top_scope_(NULL),
597 current_function_state_(NULL), 598 current_function_state_(NULL),
598 target_stack_(NULL), 599 target_stack_(NULL),
599 extension_(extension), 600 extension_(extension),
600 pre_data_(pre_data), 601 pre_data_(pre_data),
601 fni_(NULL), 602 fni_(NULL),
602 allow_natives_syntax_(allow_natives_syntax), 603 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
604 allow_lazy_((parser_flags & kAllowLazy) != 0),
603 stack_overflow_(false), 605 stack_overflow_(false),
604 parenthesized_function_(false), 606 parenthesized_function_(false),
605 harmony_scoping_(false) { 607 harmony_scoping_((parser_flags & kHarmonyScoping) != 0) {
606 AstNode::ResetIds(); 608 AstNode::ResetIds();
609 if (harmony_scoping_) scanner().SetHarmonyScoping(true);
607 } 610 }
608 611
609 612
610 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { 613 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
611 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 614 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
612 615
613 HistogramTimerScope timer(isolate()->counters()->parse()); 616 HistogramTimerScope timer(isolate()->counters()->parse());
614 Handle<String> source(String::cast(script_->source())); 617 Handle<String> source(String::cast(script_->source()));
615 isolate()->counters()->total_parse_size()->Increment(source->length()); 618 isolate()->counters()->total_parse_size()->Increment(source->length());
616 fni_ = new(zone()) FuncNameInferrer(isolate()); 619 fni_ = new(zone()) FuncNameInferrer(isolate());
(...skipping 17 matching lines...) Expand all
634 637
635 638
636 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 639 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
637 Handle<String> source, 640 Handle<String> source,
638 ZoneScope* zone_scope) { 641 ZoneScope* zone_scope) {
639 ASSERT(top_scope_ == NULL); 642 ASSERT(top_scope_ == NULL);
640 ASSERT(target_stack_ == NULL); 643 ASSERT(target_stack_ == NULL);
641 if (pre_data_ != NULL) pre_data_->Initialize(); 644 if (pre_data_ != NULL) pre_data_->Initialize();
642 645
643 // Compute the parsing mode. 646 // Compute the parsing mode.
644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 647 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 648 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
646 649
647 Handle<String> no_name = isolate()->factory()->empty_symbol(); 650 Handle<String> no_name = isolate()->factory()->empty_symbol();
648 651
649 FunctionLiteral* result = NULL; 652 FunctionLiteral* result = NULL;
650 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 653 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
651 info->SetGlobalScope(scope); 654 info->SetGlobalScope(scope);
652 if (!info->is_global()) { 655 if (!info->is_global()) {
653 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope); 656 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
654 scope = NewScope(scope, EVAL_SCOPE); 657 scope = NewScope(scope, EVAL_SCOPE);
(...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3902 return NULL; 3905 return NULL;
3903 } 3906 }
3904 done = (peek() == Token::RPAREN); 3907 done = (peek() == Token::RPAREN);
3905 if (!done) Expect(Token::COMMA, CHECK_OK); 3908 if (!done) Expect(Token::COMMA, CHECK_OK);
3906 } 3909 }
3907 Expect(Token::RPAREN, CHECK_OK); 3910 Expect(Token::RPAREN, CHECK_OK);
3908 return result; 3911 return result;
3909 } 3912 }
3910 3913
3911 3914
3915 class SingletonLogger : public ParserRecorder {
3916 public:
3917 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
3918 ~SingletonLogger() { }
3919
3920 void Reset() { has_error_ = false; }
3921
3922 virtual void LogFunction(int start,
3923 int end,
3924 int literals,
3925 int properties,
3926 StrictModeFlag strict_mode) {
3927 ASSERT(!has_error_);
3928 start_ = start;
3929 end_ = end;
3930 literals_ = literals;
3931 properties_ = properties;
3932 strict_mode_ = strict_mode;
3933 };
3934
3935 // Logs a symbol creation of a literal or identifier.
3936 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
3937 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
3938
3939 // Logs an error message and marks the log as containing an error.
3940 // Further logging will be ignored, and ExtractData will return a vector
3941 // representing the error only.
3942 virtual void LogMessage(int start,
3943 int end,
3944 const char* message,
3945 const char* argument_opt) {
3946 has_error_ = true;
3947 start_ = start;
3948 end_ = end;
3949 message_ = message;
3950 argument_opt_ = argument_opt;
3951 }
3952
3953 virtual int function_position() { return 0; }
3954
3955 virtual int symbol_position() { return 0; }
3956
3957 virtual int symbol_ids() { return -1; }
3958
3959 virtual Vector<unsigned> ExtractData() {
3960 UNREACHABLE();
3961 return Vector<unsigned>();
3962 }
3963
3964 virtual void PauseRecording() { }
3965
3966 virtual void ResumeRecording() { }
3967
3968 bool has_error() { return has_error_; }
3969
3970 int start() { return start_; }
3971 int end() { return end_; }
3972 int literals() {
3973 ASSERT(!has_error_);
3974 return literals_;
3975 }
3976 int properties() {
3977 ASSERT(!has_error_);
3978 return properties_;
3979 }
3980 StrictModeFlag strict_mode() {
3981 ASSERT(!has_error_);
3982 return strict_mode_;
3983 }
3984 const char* message() {
3985 ASSERT(has_error_);
3986 return message_;
3987 }
3988 const char* argument_opt() {
3989 ASSERT(has_error_);
3990 return argument_opt_;
3991 }
3992
3993 private:
3994 bool has_error_;
3995 int start_;
3996 int end_;
3997 // For function entries.
3998 int literals_;
3999 int properties_;
4000 StrictModeFlag strict_mode_;
4001 // For error messages.
4002 const char* message_;
4003 const char* argument_opt_;
4004 };
4005
4006
3912 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, 4007 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
3913 bool name_is_strict_reserved, 4008 bool name_is_strict_reserved,
3914 int function_token_position, 4009 int function_token_position,
3915 FunctionLiteral::Type type, 4010 FunctionLiteral::Type type,
3916 bool* ok) { 4011 bool* ok) {
3917 // Function :: 4012 // Function ::
3918 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4013 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3919 4014
3920 // Anonymous functions were passed either the empty symbol or a null 4015 // Anonymous functions were passed either the empty symbol or a null
3921 // handle as the function name. Remember if we were passed a non-empty 4016 // handle as the function name. Remember if we were passed a non-empty
3922 // handle to decide whether to invoke function name inference. 4017 // handle to decide whether to invoke function name inference.
3923 bool should_infer_name = function_name.is_null(); 4018 bool should_infer_name = function_name.is_null();
3924 4019
3925 // We want a non-null handle as the function name. 4020 // We want a non-null handle as the function name.
3926 if (should_infer_name) { 4021 if (should_infer_name) {
3927 function_name = isolate()->factory()->empty_symbol(); 4022 function_name = isolate()->factory()->empty_symbol();
3928 } 4023 }
3929 4024
3930 int num_parameters = 0; 4025 int num_parameters = 0;
3931 // Function declarations are function scoped in normal mode, so they are 4026 // Function declarations are function scoped in normal mode, so they are
3932 // hoisted. In harmony block scoping mode they are block scoped, so they 4027 // hoisted. In harmony block scoping mode they are block scoped, so they
3933 // are not hoisted. 4028 // are not hoisted.
3934 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) 4029 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_)
3935 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) 4030 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
3936 : NewScope(top_scope_, FUNCTION_SCOPE); 4031 : NewScope(top_scope_, FUNCTION_SCOPE);
3937 ZoneList<Statement*>* body = NULL; 4032 ZoneList<Statement*>* body = NULL;
3938 int materialized_literal_count; 4033 int materialized_literal_count = -1;
3939 int expected_property_count; 4034 int expected_property_count = -1;
3940 int handler_count = 0; 4035 int handler_count = 0;
3941 bool only_simple_this_property_assignments; 4036 bool only_simple_this_property_assignments;
3942 Handle<FixedArray> this_property_assignments; 4037 Handle<FixedArray> this_property_assignments;
3943 bool has_duplicate_parameters = false; 4038 bool has_duplicate_parameters = false;
3944 // Parse function body. 4039 // Parse function body.
3945 { FunctionState function_state(this, scope, isolate()); 4040 { FunctionState function_state(this, scope, isolate());
3946 top_scope_->SetScopeName(function_name); 4041 top_scope_->SetScopeName(function_name);
3947 4042
3948 // FormalParameterList :: 4043 // FormalParameterList ::
3949 // '(' (Identifier)*[','] ')' 4044 // '(' (Identifier)*[','] ')'
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 fvar_mode = CONST_HARMONY; 4096 fvar_mode = CONST_HARMONY;
4002 fvar_init_op = Token::INIT_CONST_HARMONY; 4097 fvar_init_op = Token::INIT_CONST_HARMONY;
4003 } else { 4098 } else {
4004 fvar_mode = CONST; 4099 fvar_mode = CONST;
4005 } 4100 }
4006 fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); 4101 fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode);
4007 } 4102 }
4008 4103
4009 // Determine if the function will be lazily compiled. The mode can only 4104 // Determine if the function will be lazily compiled. The mode can only
4010 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily 4105 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily
4011 // compile if we do not have preparser data for the function. 4106 // compile if we do not have preparser data for the function.
Yang 2011/11/24 14:28:41 Comment inaccurate. If I'm not mistaken, we also c
Lasse Reichstein 2011/11/24 21:16:47 That was actually correct before - if the script w
4012 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 4107 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4013 top_scope_->outer_scope()->is_global_scope() && 4108 top_scope_->outer_scope()->is_global_scope() &&
4014 top_scope_->HasTrivialOuterContext() && 4109 top_scope_->HasTrivialOuterContext() &&
4015 !parenthesized_function_ && 4110 !parenthesized_function_);
4016 pre_data() != NULL);
4017 parenthesized_function_ = false; // The bit was set for this function only. 4111 parenthesized_function_ = false; // The bit was set for this function only.
4018 4112
4019 if (is_lazily_compiled) { 4113 if (is_lazily_compiled) {
4020 int function_block_pos = scanner().location().beg_pos; 4114 int function_block_pos = scanner().location().beg_pos;
4021 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 4115 FunctionEntry entry;
4022 if (!entry.is_valid()) { 4116 if (pre_data_ != NULL) {
4023 // There is no preparser data for the function, we will not lazily 4117 entry = pre_data()->GetFunctionEntry(function_block_pos);
4024 // compile after all. 4118 if (entry.is_valid()) {
4025 is_lazily_compiled = false; 4119 if (entry.end_pos() <= function_block_pos) {
4120 // End position greater than end of stream is safe, and hard
4121 // to check.
4122 ReportInvalidPreparseData(function_name, CHECK_OK);
4123 }
4124 scanner().SeekForward(entry.end_pos() - 1);
4125
4126 scope->set_end_position(entry.end_pos());
4127 Expect(Token::RBRACE, CHECK_OK);
4128 isolate()->counters()->total_preparse_skipped()->Increment(
4129 scope->end_position() - function_block_pos);
4130 materialized_literal_count = entry.literal_count();
4131 expected_property_count = entry.property_count();
4132 top_scope_->SetStrictModeFlag(entry.strict_mode_flag());
4133 only_simple_this_property_assignments = false;
4134 this_property_assignments = isolate()->factory()->empty_fixed_array();
4135 } else {
4136 is_lazily_compiled = false;
4137 }
4026 } else { 4138 } else {
4027 scope->set_end_position(entry.end_pos()); 4139 // No preparser data, so partially parse the function now, without
4028 if (scope->end_position() <= function_block_pos) { 4140 // building an AST.
4029 // End position greater than end of stream is safe, and hard to check. 4141 SingletonLogger logger;
4030 ReportInvalidPreparseData(function_name, CHECK_OK); 4142 preparser::PreParser::PreParseResult result =
4143 LazyParseFunctionLiteral(&logger);
4144 if (result == preparser::PreParser::kPreParseStackOverflow) {
4145 // Propagate stack overflow.
4146 stack_overflow_ = true;
4147 *ok = false;
4148 return NULL;
4031 } 4149 }
4150 if (logger.has_error()) {
4151 const char* arg = logger.argument_opt();
4152 Vector<const char*> args;
4153 if (arg != NULL) {
4154 args = Vector<const char*>(&arg, 1);
4155 }
4156 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4157 logger.message(), args);
4158 *ok = false;
4159 return NULL;
4160 }
4161 scope->set_end_position(logger.end());
4162 Expect(Token::RBRACE, CHECK_OK);
4032 isolate()->counters()->total_preparse_skipped()->Increment( 4163 isolate()->counters()->total_preparse_skipped()->Increment(
4033 scope->end_position() - function_block_pos); 4164 scope->end_position() - function_block_pos);
4034 // Seek to position just before terminal '}'. 4165 materialized_literal_count = logger.literals();
4035 scanner().SeekForward(scope->end_position() - 1); 4166 expected_property_count = logger.properties();
4036 materialized_literal_count = entry.literal_count(); 4167 top_scope_->SetStrictModeFlag(logger.strict_mode());
4037 expected_property_count = entry.property_count();
4038 top_scope_->SetStrictModeFlag(entry.strict_mode_flag());
4039 only_simple_this_property_assignments = false; 4168 only_simple_this_property_assignments = false;
4040 this_property_assignments = isolate()->factory()->empty_fixed_array(); 4169 this_property_assignments = isolate()->factory()->empty_fixed_array();
4041 Expect(Token::RBRACE, CHECK_OK);
4042 } 4170 }
4043 } 4171 }
4044 4172
4045 if (!is_lazily_compiled) { 4173 if (!is_lazily_compiled) {
4046 body = new(zone()) ZoneList<Statement*>(8); 4174 body = new(zone()) ZoneList<Statement*>(8);
4047 if (fvar != NULL) { 4175 if (fvar != NULL) {
4048 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); 4176 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
4049 fproxy->BindTo(fvar); 4177 fproxy->BindTo(fvar);
4050 body->Add(new(zone()) ExpressionStatement( 4178 body->Add(new(zone()) ExpressionStatement(
4051 new(zone()) Assignment(isolate(), 4179 new(zone()) Assignment(isolate(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 num_parameters, 4260 num_parameters,
4133 type, 4261 type,
4134 has_duplicate_parameters); 4262 has_duplicate_parameters);
4135 function_literal->set_function_token_position(function_token_position); 4263 function_literal->set_function_token_position(function_token_position);
4136 4264
4137 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4265 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4138 return function_literal; 4266 return function_literal;
4139 } 4267 }
4140 4268
4141 4269
4270 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4271 SingletonLogger* logger) {
4272 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4273 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4274 int flags = kAllowLazy;
4275 if (allow_natives_syntax_) flags |= kAllowNativesSyntax;
4276 if (scanner_.HarmonyScoping()) flags |= kHarmonyScoping;
4277
4278 if (reusable_preparser_ == NULL) {
4279 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4280 bool allow_lazy = true;
4281 reusable_preparser_ = new preparser::PreParser(&scanner_,
4282 NULL,
4283 stack_limit,
4284 allow_lazy,
4285 allow_natives_syntax_);
4286 }
4287 preparser::PreParser::PreParseResult result =
4288 reusable_preparser_->PreParseLazyFunction(top_scope_->is_strict_mode(),
4289 logger);
4290 return result;
4291 }
4292
4293
4142 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4294 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4143 // CallRuntime :: 4295 // CallRuntime ::
4144 // '%' Identifier Arguments 4296 // '%' Identifier Arguments
4145 4297
4146 Expect(Token::MOD, CHECK_OK); 4298 Expect(Token::MOD, CHECK_OK);
4147 Handle<String> name = ParseIdentifier(CHECK_OK); 4299 Handle<String> name = ParseIdentifier(CHECK_OK);
4148 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4300 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4149 4301
4150 if (extension_ != NULL) { 4302 if (extension_ != NULL) {
4151 // The extension structures are only accessible while parsing the 4303 // The extension structures are only accessible while parsing the
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
5350 5502
5351 // Create a Scanner for the preparser to use as input, and preparse the source. 5503 // Create a Scanner for the preparser to use as input, and preparse the source.
5352 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5504 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
5353 int flags, 5505 int flags,
5354 ParserRecorder* recorder) { 5506 ParserRecorder* recorder) {
5355 Isolate* isolate = Isolate::Current(); 5507 Isolate* isolate = Isolate::Current();
5356 Scanner scanner(isolate->unicode_cache()); 5508 Scanner scanner(isolate->unicode_cache());
5357 scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0); 5509 scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0);
5358 scanner.Initialize(source); 5510 scanner.Initialize(source);
5359 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5511 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5360 if (!preparser::PreParser::PreParseProgram(&scanner, 5512 preparser::PreParser::PreParseResult result =
5361 recorder, 5513 preparser::PreParser::PreParseProgram(&scanner,
5362 flags, 5514 recorder,
5363 stack_limit)) { 5515 flags,
5516 stack_limit);
5517 if (result == preparser::PreParser::kPreParseStackOverflow) {
5364 isolate->StackOverflow(); 5518 isolate->StackOverflow();
5365 return NULL; 5519 return NULL;
5366 } 5520 }
5367 5521
5368 // Extract the accumulated data from the recorder as a single 5522 // Extract the accumulated data from the recorder as a single
5369 // contiguous vector that we are responsible for disposing. 5523 // contiguous vector that we are responsible for disposing.
5370 Vector<unsigned> store = recorder->ExtractData(); 5524 Vector<unsigned> store = recorder->ExtractData();
5371 return new ScriptDataImpl(store); 5525 return new ScriptDataImpl(store);
5372 } 5526 }
5373 5527
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5416 result->tree = tree; 5570 result->tree = tree;
5417 int capture_count = parser.captures_started(); 5571 int capture_count = parser.captures_started();
5418 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5572 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5419 result->contains_anchor = parser.contains_anchor(); 5573 result->contains_anchor = parser.contains_anchor();
5420 result->capture_count = capture_count; 5574 result->capture_count = capture_count;
5421 } 5575 }
5422 return !parser.failed(); 5576 return !parser.failed();
5423 } 5577 }
5424 5578
5425 5579
5426 bool ParserApi::Parse(CompilationInfo* info) { 5580 bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
5427 ASSERT(info->function() == NULL); 5581 ASSERT(info->function() == NULL);
5428 FunctionLiteral* result = NULL; 5582 FunctionLiteral* result = NULL;
5429 Handle<Script> script = info->script(); 5583 Handle<Script> script = info->script();
5430 bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping; 5584 if (!info->is_native() && FLAG_harmony_scoping) {
5585 // Harmony scoping is requested.
5586 parsing_flags |= kHarmonyScoping;
5587 }
5588 if (FLAG_allow_natives_syntax || info->is_native()) {
5589 // We requre %identifier(..) syntax.
5590 parsing_flags |= kAllowNativesSyntax;
5591 }
5431 if (info->is_lazy()) { 5592 if (info->is_lazy()) {
5432 ASSERT(!info->is_eval()); 5593 ASSERT(!info->is_eval());
5433 bool allow_natives_syntax = 5594 Parser parser(script, parsing_flags, NULL, NULL);
5434 FLAG_allow_natives_syntax ||
5435 info->is_native();
5436 Parser parser(script, allow_natives_syntax, NULL, NULL);
5437 parser.SetHarmonyScoping(harmony_scoping);
5438 result = parser.ParseLazy(info); 5595 result = parser.ParseLazy(info);
5439 } else { 5596 } else {
5440 // Whether we allow %identifier(..) syntax.
5441 bool allow_natives_syntax =
5442 info->is_native() || FLAG_allow_natives_syntax;
5443 ScriptDataImpl* pre_data = info->pre_parse_data(); 5597 ScriptDataImpl* pre_data = info->pre_parse_data();
5444 Parser parser(script, 5598 Parser parser(script, parsing_flags, info->extension(), pre_data);
5445 allow_natives_syntax,
5446 info->extension(),
5447 pre_data);
5448 parser.SetHarmonyScoping(harmony_scoping);
5449 if (pre_data != NULL && pre_data->has_error()) { 5599 if (pre_data != NULL && pre_data->has_error()) {
5450 Scanner::Location loc = pre_data->MessageLocation(); 5600 Scanner::Location loc = pre_data->MessageLocation();
5451 const char* message = pre_data->BuildMessage(); 5601 const char* message = pre_data->BuildMessage();
5452 Vector<const char*> args = pre_data->BuildArgs(); 5602 Vector<const char*> args = pre_data->BuildArgs();
5453 parser.ReportMessageAt(loc, message, args); 5603 parser.ReportMessageAt(loc, message, args);
5454 DeleteArray(message); 5604 DeleteArray(message);
5455 for (int i = 0; i < args.length(); i++) { 5605 for (int i = 0; i < args.length(); i++) {
5456 DeleteArray(args[i]); 5606 DeleteArray(args[i]);
5457 } 5607 }
5458 DeleteArray(args.start()); 5608 DeleteArray(args.start());
5459 ASSERT(info->isolate()->has_pending_exception()); 5609 ASSERT(info->isolate()->has_pending_exception());
5460 } else { 5610 } else {
5461 result = parser.ParseProgram(info); 5611 result = parser.ParseProgram(info);
5462 } 5612 }
5463 } 5613 }
5464 info->SetFunction(result); 5614 info->SetFunction(result);
5465 return (result != NULL); 5615 return (result != NULL);
5466 } 5616 }
5467 5617
5468 } } // namespace v8::internal 5618 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698