Chromium Code Reviews| 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 |