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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |