| 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 |