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

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: Updated to match tip of bleeding edge 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 scanner().SetHarmonyScoping(FLAG_harmony_scoping);
606 AstNode::ResetIds(); 607 AstNode::ResetIds();
608 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
609 scanner().SetHarmonyScoping(true);
610 }
607 } 611 }
608 612
609 613
610 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { 614 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
611 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 615 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
612 616
613 HistogramTimerScope timer(isolate()->counters()->parse()); 617 HistogramTimerScope timer(isolate()->counters()->parse());
614 Handle<String> source(String::cast(script_->source())); 618 Handle<String> source(String::cast(script_->source()));
615 isolate()->counters()->total_parse_size()->Increment(source->length()); 619 isolate()->counters()->total_parse_size()->Increment(source->length());
616 fni_ = new(zone()) FuncNameInferrer(isolate()); 620 fni_ = new(zone()) FuncNameInferrer(isolate());
(...skipping 17 matching lines...) Expand all
634 638
635 639
636 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 640 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
637 Handle<String> source, 641 Handle<String> source,
638 ZoneScope* zone_scope) { 642 ZoneScope* zone_scope) {
639 ASSERT(top_scope_ == NULL); 643 ASSERT(top_scope_ == NULL);
640 ASSERT(target_stack_ == NULL); 644 ASSERT(target_stack_ == NULL);
641 if (pre_data_ != NULL) pre_data_->Initialize(); 645 if (pre_data_ != NULL) pre_data_->Initialize();
642 646
643 // Compute the parsing mode. 647 // Compute the parsing mode.
644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 648 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 649 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
646 650
647 Handle<String> no_name = isolate()->factory()->empty_symbol(); 651 Handle<String> no_name = isolate()->factory()->empty_symbol();
648 652
649 FunctionLiteral* result = NULL; 653 FunctionLiteral* result = NULL;
650 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 654 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
651 info->SetGlobalScope(scope); 655 info->SetGlobalScope(scope);
652 if (!info->is_global()) { 656 if (!info->is_global()) {
653 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope); 657 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
654 scope = NewScope(scope, EVAL_SCOPE); 658 scope = NewScope(scope, EVAL_SCOPE);
(...skipping 3249 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 return NULL; 3908 return NULL;
3905 } 3909 }
3906 done = (peek() == Token::RPAREN); 3910 done = (peek() == Token::RPAREN);
3907 if (!done) Expect(Token::COMMA, CHECK_OK); 3911 if (!done) Expect(Token::COMMA, CHECK_OK);
3908 } 3912 }
3909 Expect(Token::RPAREN, CHECK_OK); 3913 Expect(Token::RPAREN, CHECK_OK);
3910 return result; 3914 return result;
3911 } 3915 }
3912 3916
3913 3917
3918 class SingletonLogger : public ParserRecorder {
3919 public:
3920 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
3921 ~SingletonLogger() { }
3922
3923 void Reset() { has_error_ = false; }
3924
3925 virtual void LogFunction(int start,
3926 int end,
3927 int literals,
3928 int properties,
3929 LanguageMode mode) {
3930 ASSERT(!has_error_);
3931 start_ = start;
3932 end_ = end;
3933 literals_ = literals;
3934 properties_ = properties;
3935 mode_ = mode;
3936 };
3937
3938 // Logs a symbol creation of a literal or identifier.
3939 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
3940 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
3941
3942 // Logs an error message and marks the log as containing an error.
3943 // Further logging will be ignored, and ExtractData will return a vector
3944 // representing the error only.
3945 virtual void LogMessage(int start,
3946 int end,
3947 const char* message,
3948 const char* argument_opt) {
3949 has_error_ = true;
3950 start_ = start;
3951 end_ = end;
3952 message_ = message;
3953 argument_opt_ = argument_opt;
3954 }
3955
3956 virtual int function_position() { return 0; }
3957
3958 virtual int symbol_position() { return 0; }
3959
3960 virtual int symbol_ids() { return -1; }
3961
3962 virtual Vector<unsigned> ExtractData() {
3963 UNREACHABLE();
3964 return Vector<unsigned>();
3965 }
3966
3967 virtual void PauseRecording() { }
3968
3969 virtual void ResumeRecording() { }
3970
3971 bool has_error() { return has_error_; }
3972
3973 int start() { return start_; }
3974 int end() { return end_; }
3975 int literals() {
3976 ASSERT(!has_error_);
3977 return literals_;
3978 }
3979 int properties() {
3980 ASSERT(!has_error_);
3981 return properties_;
3982 }
3983 LanguageMode language_mode() {
3984 ASSERT(!has_error_);
3985 return mode_;
3986 }
3987 const char* message() {
3988 ASSERT(has_error_);
3989 return message_;
3990 }
3991 const char* argument_opt() {
3992 ASSERT(has_error_);
3993 return argument_opt_;
3994 }
3995
3996 private:
3997 bool has_error_;
3998 int start_;
3999 int end_;
4000 // For function entries.
4001 int literals_;
4002 int properties_;
4003 LanguageMode mode_;
4004 // For error messages.
4005 const char* message_;
4006 const char* argument_opt_;
4007 };
4008
4009
3914 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, 4010 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
3915 bool name_is_strict_reserved, 4011 bool name_is_strict_reserved,
3916 int function_token_position, 4012 int function_token_position,
3917 FunctionLiteral::Type type, 4013 FunctionLiteral::Type type,
3918 bool* ok) { 4014 bool* ok) {
3919 // Function :: 4015 // Function ::
3920 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4016 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3921 4017
3922 // Anonymous functions were passed either the empty symbol or a null 4018 // Anonymous functions were passed either the empty symbol or a null
3923 // handle as the function name. Remember if we were passed a non-empty 4019 // handle as the function name. Remember if we were passed a non-empty
3924 // handle to decide whether to invoke function name inference. 4020 // handle to decide whether to invoke function name inference.
3925 bool should_infer_name = function_name.is_null(); 4021 bool should_infer_name = function_name.is_null();
3926 4022
3927 // We want a non-null handle as the function name. 4023 // We want a non-null handle as the function name.
3928 if (should_infer_name) { 4024 if (should_infer_name) {
3929 function_name = isolate()->factory()->empty_symbol(); 4025 function_name = isolate()->factory()->empty_symbol();
3930 } 4026 }
3931 4027
3932 int num_parameters = 0; 4028 int num_parameters = 0;
3933 // Function declarations are function scoped in normal mode, so they are 4029 // Function declarations are function scoped in normal mode, so they are
3934 // hoisted. In harmony block scoping mode they are block scoped, so they 4030 // hoisted. In harmony block scoping mode they are block scoped, so they
3935 // are not hoisted. 4031 // are not hoisted.
3936 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode()) 4032 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
3937 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) 4033 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
3938 : NewScope(top_scope_, FUNCTION_SCOPE); 4034 : NewScope(top_scope_, FUNCTION_SCOPE);
3939 ZoneList<Statement*>* body = NULL; 4035 ZoneList<Statement*>* body = NULL;
3940 int materialized_literal_count; 4036 int materialized_literal_count = -1;
3941 int expected_property_count; 4037 int expected_property_count = -1;
3942 int handler_count = 0; 4038 int handler_count = 0;
3943 bool only_simple_this_property_assignments; 4039 bool only_simple_this_property_assignments;
3944 Handle<FixedArray> this_property_assignments; 4040 Handle<FixedArray> this_property_assignments;
3945 bool has_duplicate_parameters = false; 4041 bool has_duplicate_parameters = false;
3946 // Parse function body. 4042 // Parse function body.
3947 { FunctionState function_state(this, scope, isolate()); 4043 { FunctionState function_state(this, scope, isolate());
3948 top_scope_->SetScopeName(function_name); 4044 top_scope_->SetScopeName(function_name);
3949 4045
3950 // FormalParameterList :: 4046 // FormalParameterList ::
3951 // '(' (Identifier)*[','] ')' 4047 // '(' (Identifier)*[','] ')'
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 VariableMode fvar_mode; 4097 VariableMode fvar_mode;
4002 if (is_extended_mode()) { 4098 if (is_extended_mode()) {
4003 fvar_mode = CONST_HARMONY; 4099 fvar_mode = CONST_HARMONY;
4004 fvar_init_op = Token::INIT_CONST_HARMONY; 4100 fvar_init_op = Token::INIT_CONST_HARMONY;
4005 } else { 4101 } else {
4006 fvar_mode = CONST; 4102 fvar_mode = CONST;
4007 } 4103 }
4008 fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); 4104 fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode);
4009 } 4105 }
4010 4106
4011 // Determine if the function will be lazily compiled. The mode can only 4107 // Determine whether the function will be lazily compiled.
4012 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily 4108 // The heuristics are:
4013 // compile if we do not have preparser data for the function. 4109 // - It must not have been prohibited by the caller to Parse (some callers
4110 // need a full AST).
4111 // - The outer scope must be trivial (only global variables in scope).
4112 // - The function mustn't be a function expression with an open parenthesis
4113 // before; we consider that a hint that the function will be called
4114 // immediately, and it would be a waste of time to make it lazily
4115 // compiled.
4116 // These are all things we can know at this point, without looking at the
4117 // function itself.
4014 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 4118 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4015 top_scope_->outer_scope()->is_global_scope() && 4119 top_scope_->outer_scope()->is_global_scope() &&
4016 top_scope_->HasTrivialOuterContext() && 4120 top_scope_->HasTrivialOuterContext() &&
4017 !parenthesized_function_ && 4121 !parenthesized_function_);
4018 pre_data() != NULL);
4019 parenthesized_function_ = false; // The bit was set for this function only. 4122 parenthesized_function_ = false; // The bit was set for this function only.
4020 4123
4021 if (is_lazily_compiled) { 4124 if (is_lazily_compiled) {
4022 int function_block_pos = scanner().location().beg_pos; 4125 int function_block_pos = scanner().location().beg_pos;
4023 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 4126 FunctionEntry entry;
4024 if (!entry.is_valid()) { 4127 if (pre_data_ != NULL) {
4025 // There is no preparser data for the function, we will not lazily 4128 // If we have pre_data_, we use it to skip parsing the function body.
4026 // compile after all. 4129 // the preparser data contains the information we need to construct the
4027 is_lazily_compiled = false; 4130 // lazy function.
4131 entry = pre_data()->GetFunctionEntry(function_block_pos);
4132 if (entry.is_valid()) {
4133 if (entry.end_pos() <= function_block_pos) {
4134 // End position greater than end of stream is safe, and hard
4135 // to check.
4136 ReportInvalidPreparseData(function_name, CHECK_OK);
4137 }
4138 scanner().SeekForward(entry.end_pos() - 1);
4139
4140 scope->set_end_position(entry.end_pos());
4141 Expect(Token::RBRACE, CHECK_OK);
4142 isolate()->counters()->total_preparse_skipped()->Increment(
4143 scope->end_position() - function_block_pos);
4144 materialized_literal_count = entry.literal_count();
4145 expected_property_count = entry.property_count();
4146 top_scope_->SetLanguageMode(entry.language_mode());
4147 only_simple_this_property_assignments = false;
4148 this_property_assignments = isolate()->factory()->empty_fixed_array();
4149 } else {
4150 is_lazily_compiled = false;
4151 }
4028 } else { 4152 } else {
4029 scope->set_end_position(entry.end_pos()); 4153 // With no preparser data, we partially parse the function, without
4030 if (scope->end_position() <= function_block_pos) { 4154 // building an AST. This gathers the data needed to build a lazy
4031 // End position greater than end of stream is safe, and hard to check. 4155 // function.
4032 ReportInvalidPreparseData(function_name, CHECK_OK); 4156 SingletonLogger logger;
4157 preparser::PreParser::PreParseResult result =
4158 LazyParseFunctionLiteral(&logger);
4159 if (result == preparser::PreParser::kPreParseStackOverflow) {
4160 // Propagate stack overflow.
4161 stack_overflow_ = true;
4162 *ok = false;
4163 return NULL;
4033 } 4164 }
4165 if (logger.has_error()) {
4166 const char* arg = logger.argument_opt();
4167 Vector<const char*> args;
4168 if (arg != NULL) {
4169 args = Vector<const char*>(&arg, 1);
4170 }
4171 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4172 logger.message(), args);
4173 *ok = false;
4174 return NULL;
4175 }
4176 scope->set_end_position(logger.end());
4177 Expect(Token::RBRACE, CHECK_OK);
4034 isolate()->counters()->total_preparse_skipped()->Increment( 4178 isolate()->counters()->total_preparse_skipped()->Increment(
4035 scope->end_position() - function_block_pos); 4179 scope->end_position() - function_block_pos);
4036 // Seek to position just before terminal '}'. 4180 materialized_literal_count = logger.literals();
4037 scanner().SeekForward(scope->end_position() - 1); 4181 expected_property_count = logger.properties();
4038 materialized_literal_count = entry.literal_count(); 4182 top_scope_->SetLanguageMode(logger.language_mode());
4039 expected_property_count = entry.property_count();
4040 top_scope_->SetLanguageMode(entry.language_mode());
4041 only_simple_this_property_assignments = false; 4183 only_simple_this_property_assignments = false;
4042 this_property_assignments = isolate()->factory()->empty_fixed_array(); 4184 this_property_assignments = isolate()->factory()->empty_fixed_array();
4043 Expect(Token::RBRACE, CHECK_OK);
4044 } 4185 }
4045 } 4186 }
4046 4187
4047 if (!is_lazily_compiled) { 4188 if (!is_lazily_compiled) {
4048 body = new(zone()) ZoneList<Statement*>(8); 4189 body = new(zone()) ZoneList<Statement*>(8);
4049 if (fvar != NULL) { 4190 if (fvar != NULL) {
4050 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); 4191 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
4051 fproxy->BindTo(fvar); 4192 fproxy->BindTo(fvar);
4052 body->Add(new(zone()) ExpressionStatement( 4193 body->Add(new(zone()) ExpressionStatement(
4053 new(zone()) Assignment(isolate(), 4194 new(zone()) Assignment(isolate(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4134 num_parameters, 4275 num_parameters,
4135 type, 4276 type,
4136 has_duplicate_parameters); 4277 has_duplicate_parameters);
4137 function_literal->set_function_token_position(function_token_position); 4278 function_literal->set_function_token_position(function_token_position);
4138 4279
4139 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4280 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4140 return function_literal; 4281 return function_literal;
4141 } 4282 }
4142 4283
4143 4284
4285 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4286 SingletonLogger* logger) {
4287 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4288 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4289
4290 if (reusable_preparser_ == NULL) {
4291 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4292 bool do_allow_lazy = true;
4293 reusable_preparser_ = new preparser::PreParser(&scanner_,
4294 NULL,
4295 stack_limit,
4296 do_allow_lazy,
4297 allow_natives_syntax_);
4298 }
4299 preparser::PreParser::PreParseResult result =
4300 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4301 logger);
4302 return result;
4303 }
4304
4305
4144 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4306 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4145 // CallRuntime :: 4307 // CallRuntime ::
4146 // '%' Identifier Arguments 4308 // '%' Identifier Arguments
4147 4309
4148 Expect(Token::MOD, CHECK_OK); 4310 Expect(Token::MOD, CHECK_OK);
4149 Handle<String> name = ParseIdentifier(CHECK_OK); 4311 Handle<String> name = ParseIdentifier(CHECK_OK);
4150 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4312 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4151 4313
4152 if (extension_ != NULL) { 4314 if (extension_ != NULL) {
4153 // The extension structures are only accessible while parsing the 4315 // The extension structures are only accessible while parsing the
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
5353 // Create a Scanner for the preparser to use as input, and preparse the source. 5515 // Create a Scanner for the preparser to use as input, and preparse the source.
5354 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5516 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
5355 int flags, 5517 int flags,
5356 ParserRecorder* recorder) { 5518 ParserRecorder* recorder) {
5357 Isolate* isolate = Isolate::Current(); 5519 Isolate* isolate = Isolate::Current();
5358 HistogramTimerScope timer(isolate->counters()->pre_parse()); 5520 HistogramTimerScope timer(isolate->counters()->pre_parse());
5359 Scanner scanner(isolate->unicode_cache()); 5521 Scanner scanner(isolate->unicode_cache());
5360 scanner.SetHarmonyScoping(FLAG_harmony_scoping); 5522 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5361 scanner.Initialize(source); 5523 scanner.Initialize(source);
5362 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5524 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5363 if (!preparser::PreParser::PreParseProgram(&scanner, 5525 preparser::PreParser::PreParseResult result =
5364 recorder, 5526 preparser::PreParser::PreParseProgram(&scanner,
5365 flags, 5527 recorder,
5366 stack_limit)) { 5528 flags,
5529 stack_limit);
5530 if (result == preparser::PreParser::kPreParseStackOverflow) {
5367 isolate->StackOverflow(); 5531 isolate->StackOverflow();
5368 return NULL; 5532 return NULL;
5369 } 5533 }
5370 5534
5371 // Extract the accumulated data from the recorder as a single 5535 // Extract the accumulated data from the recorder as a single
5372 // contiguous vector that we are responsible for disposing. 5536 // contiguous vector that we are responsible for disposing.
5373 Vector<unsigned> store = recorder->ExtractData(); 5537 Vector<unsigned> store = recorder->ExtractData();
5374 return new ScriptDataImpl(store); 5538 return new ScriptDataImpl(store);
5375 } 5539 }
5376 5540
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 result->tree = tree; 5583 result->tree = tree;
5420 int capture_count = parser.captures_started(); 5584 int capture_count = parser.captures_started();
5421 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5585 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5422 result->contains_anchor = parser.contains_anchor(); 5586 result->contains_anchor = parser.contains_anchor();
5423 result->capture_count = capture_count; 5587 result->capture_count = capture_count;
5424 } 5588 }
5425 return !parser.failed(); 5589 return !parser.failed();
5426 } 5590 }
5427 5591
5428 5592
5429 bool ParserApi::Parse(CompilationInfo* info) { 5593 bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
5430 ASSERT(info->function() == NULL); 5594 ASSERT(info->function() == NULL);
5431 FunctionLiteral* result = NULL; 5595 FunctionLiteral* result = NULL;
5432 Handle<Script> script = info->script(); 5596 Handle<Script> script = info->script();
5597 ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
5598 if (!info->is_native() && FLAG_harmony_scoping) {
5599 // Harmony scoping is requested.
5600 parsing_flags |= EXTENDED_MODE;
5601 }
5602 if (FLAG_allow_natives_syntax || info->is_native()) {
5603 // We requre %identifier(..) syntax.
5604 parsing_flags |= kAllowNativesSyntax;
5605 }
5433 if (info->is_lazy()) { 5606 if (info->is_lazy()) {
5434 ASSERT(!info->is_eval()); 5607 ASSERT(!info->is_eval());
5435 bool allow_natives_syntax = 5608 Parser parser(script, parsing_flags, NULL, NULL);
5436 FLAG_allow_natives_syntax ||
5437 info->is_native();
5438 Parser parser(script, allow_natives_syntax, NULL, NULL);
5439 result = parser.ParseLazy(info); 5609 result = parser.ParseLazy(info);
5440 } else { 5610 } else {
5441 // Whether we allow %identifier(..) syntax.
5442 bool allow_natives_syntax =
5443 info->is_native() || FLAG_allow_natives_syntax;
5444 ScriptDataImpl* pre_data = info->pre_parse_data(); 5611 ScriptDataImpl* pre_data = info->pre_parse_data();
5445 Parser parser(script, 5612 Parser parser(script, parsing_flags, info->extension(), pre_data);
5446 allow_natives_syntax,
5447 info->extension(),
5448 pre_data);
5449 if (pre_data != NULL && pre_data->has_error()) { 5613 if (pre_data != NULL && pre_data->has_error()) {
5450 Scanner::Location loc = pre_data->MessageLocation(); 5614 Scanner::Location loc = pre_data->MessageLocation();
5451 const char* message = pre_data->BuildMessage(); 5615 const char* message = pre_data->BuildMessage();
5452 Vector<const char*> args = pre_data->BuildArgs(); 5616 Vector<const char*> args = pre_data->BuildArgs();
5453 parser.ReportMessageAt(loc, message, args); 5617 parser.ReportMessageAt(loc, message, args);
5454 DeleteArray(message); 5618 DeleteArray(message);
5455 for (int i = 0; i < args.length(); i++) { 5619 for (int i = 0; i < args.length(); i++) {
5456 DeleteArray(args[i]); 5620 DeleteArray(args[i]);
5457 } 5621 }
5458 DeleteArray(args.start()); 5622 DeleteArray(args.start());
5459 ASSERT(info->isolate()->has_pending_exception()); 5623 ASSERT(info->isolate()->has_pending_exception());
5460 } else { 5624 } else {
5461 result = parser.ParseProgram(info); 5625 result = parser.ParseProgram(info);
5462 } 5626 }
5463 } 5627 }
5464 info->SetFunction(result); 5628 info->SetFunction(result);
5465 return (result != NULL); 5629 return (result != NULL);
5466 } 5630 }
5467 5631
5468 } } // namespace v8::internal 5632 } } // 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