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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |