| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| 11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
| 12 #include "src/char-predicates-inl.h" | 12 #include "src/char-predicates-inl.h" |
| 13 #include "src/codegen.h" | 13 #include "src/codegen.h" |
| 14 #include "src/compiler.h" | 14 #include "src/compiler.h" |
| 15 #include "src/messages.h" | 15 #include "src/messages.h" |
| 16 #include "src/parser.h" | 16 #include "src/parser.h" |
| 17 #include "src/preparser.h" | 17 #include "src/preparser.h" |
| 18 #include "src/runtime/runtime.h" | 18 #include "src/runtime/runtime.h" |
| 19 #include "src/scanner-character-streams.h" | 19 #include "src/scanner-character-streams.h" |
| 20 #include "src/scopeinfo.h" | 20 #include "src/scopeinfo.h" |
| 21 #include "src/string-stream.h" | 21 #include "src/string-stream.h" |
| 22 | 22 |
| 23 namespace v8 { | 23 namespace v8 { |
| 24 namespace internal { | 24 namespace internal { |
| 25 | 25 |
| 26 |
| 27 int FunctionEntry::Size() { |
| 28 if (backing_.is_empty()) return 0; |
| 29 int result = kSize; |
| 30 for (int i = 0; i < identifier_count(); i++) { |
| 31 result += 1; // is_one_byte |
| 32 CHECK(result < backing_.length()); |
| 33 const int byte_length = backing_[result]; |
| 34 const int word_length = |
| 35 1 + (((byte_length * sizeof(unsigned char)) - 1) / sizeof(unsigned)); |
| 36 result += 1; // length |
| 37 result += word_length; |
| 38 } |
| 39 CHECK(result <= backing_.length()); |
| 40 return result; |
| 41 } |
| 42 |
| 43 |
| 44 const AstRawString* FunctionEntry::IdentifierIterator::Next( |
| 45 AstValueFactory* ast_value_factory) { |
| 46 // FunctionEntry::size() is always called when an IdentifierIterator is |
| 47 // constructed (by FunctionEntry::Identifiers), and FunctionEntry::size() |
| 48 // CHECKs that the identifiers don't run past the end of backing_ so we don't |
| 49 // have to CHECK that here. |
| 50 DCHECK(!AtEnd()); |
| 51 const bool is_one_byte = static_cast<bool>(backing_.first()); |
| 52 backing_ += 1; |
| 53 const int length = backing_.first(); |
| 54 backing_ += 1; |
| 55 if (is_one_byte) { |
| 56 Vector<const uint8_t> data = Vector<const uint8_t>::cast(backing_); |
| 57 data.Truncate(length); |
| 58 const int word_length = |
| 59 1 + (((length * sizeof(uint8_t)) - 1) / sizeof(unsigned)); |
| 60 backing_ += word_length; |
| 61 return ast_value_factory->GetOneByteString(data); |
| 62 } else { |
| 63 Vector<const uint16_t> data = Vector<const uint16_t>::cast(backing_); |
| 64 data.Truncate(length); |
| 65 const int word_length = |
| 66 1 + (((length * sizeof(uint16_t)) - 1) / sizeof(unsigned)); |
| 67 backing_ += word_length; |
| 68 return ast_value_factory->GetTwoByteString(data); |
| 69 } |
| 70 } |
| 71 |
| 72 |
| 26 RegExpBuilder::RegExpBuilder(Zone* zone) | 73 RegExpBuilder::RegExpBuilder(Zone* zone) |
| 27 : zone_(zone), | 74 : zone_(zone), |
| 28 pending_empty_(false), | 75 pending_empty_(false), |
| 29 characters_(NULL), | 76 characters_(NULL), |
| 30 terms_(), | 77 terms_(), |
| 31 alternatives_() | 78 alternatives_() |
| 32 #ifdef DEBUG | 79 #ifdef DEBUG |
| 33 , last_added_(ADD_NONE) | 80 , last_added_(ADD_NONE) |
| 34 #endif | 81 #endif |
| 35 {} | 82 {} |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); | 228 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); |
| 182 LAST(ADD_TERM); | 229 LAST(ADD_TERM); |
| 183 } | 230 } |
| 184 | 231 |
| 185 | 232 |
| 186 FunctionEntry ParseData::GetFunctionEntry(int start) { | 233 FunctionEntry ParseData::GetFunctionEntry(int start) { |
| 187 // The current pre-data entry must be a FunctionEntry with the given | 234 // The current pre-data entry must be a FunctionEntry with the given |
| 188 // start position. | 235 // start position. |
| 189 if ((function_index_ + FunctionEntry::kSize <= Length()) && | 236 if ((function_index_ + FunctionEntry::kSize <= Length()) && |
| 190 (static_cast<int>(Data()[function_index_]) == start)) { | 237 (static_cast<int>(Data()[function_index_]) == start)) { |
| 191 int index = function_index_; | 238 int remaining_length = Length() - function_index_; |
| 192 function_index_ += FunctionEntry::kSize; | 239 Vector<unsigned> subvector(&(Data()[function_index_]), remaining_length); |
| 193 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); | 240 FunctionEntry entry(subvector); |
| 194 return FunctionEntry(subvector); | 241 int entry_size = entry.Size(); |
| 242 CHECK(entry_size <= remaining_length); |
| 243 function_index_ += entry_size; |
| 244 return entry; |
| 195 } | 245 } |
| 196 return FunctionEntry(); | 246 return FunctionEntry(); |
| 197 } | 247 } |
| 198 | 248 |
| 199 | 249 |
| 200 int ParseData::FunctionCount() { | 250 int ParseData::FunctionCount() { |
| 201 int functions_size = FunctionsSize(); | 251 int function_count = 0; |
| 202 if (functions_size < 0) return 0; | 252 int function_index = PreparseDataConstants::kHeaderSize; |
| 203 if (functions_size % FunctionEntry::kSize != 0) return 0; | 253 while (function_index < Length()) { |
| 204 return functions_size / FunctionEntry::kSize; | 254 function_count += 1; |
| 255 Vector<unsigned> subvector(&(Data()[function_index]), |
| 256 Length() - function_index); |
| 257 FunctionEntry entry(subvector); |
| 258 function_index += entry.Size(); |
| 259 } |
| 260 return function_count; |
| 205 } | 261 } |
| 206 | 262 |
| 207 | 263 |
| 208 bool ParseData::IsSane() { | 264 bool ParseData::IsSane() { |
| 209 // Check that the header data is valid and doesn't specify | 265 // Check that the header data is valid and doesn't specify |
| 210 // point to positions outside the store. | 266 // point to positions outside the store. |
| 211 int data_length = Length(); | 267 int data_length = Length(); |
| 212 if (data_length < PreparseDataConstants::kHeaderSize) return false; | 268 if (data_length < PreparseDataConstants::kHeaderSize) return false; |
| 213 if (Magic() != PreparseDataConstants::kMagicNumber) return false; | 269 if (Magic() != PreparseDataConstants::kMagicNumber) return false; |
| 214 if (Version() != PreparseDataConstants::kCurrentVersion) return false; | 270 if (Version() != PreparseDataConstants::kCurrentVersion) return false; |
| 215 if (HasError()) return false; | 271 if (HasError()) return false; |
| 216 // Check that the space allocated for function entries is sane. | 272 // Check that the space allocated for function entries is sane. |
| 217 int functions_size = FunctionsSize(); | 273 int functions_size = FunctionsSize(); |
| 218 if (functions_size < 0) return false; | 274 if (functions_size < 0) return false; |
| 219 if (functions_size % FunctionEntry::kSize != 0) return false; | |
| 220 // Check that the total size has room for header and function entries. | 275 // Check that the total size has room for header and function entries. |
| 221 int minimum_size = | 276 int minimum_size = |
| 222 PreparseDataConstants::kHeaderSize + functions_size; | 277 PreparseDataConstants::kHeaderSize + functions_size; |
| 223 if (data_length < minimum_size) return false; | 278 if (data_length < minimum_size) return false; |
| 224 return true; | 279 return true; |
| 225 } | 280 } |
| 226 | 281 |
| 227 | 282 |
| 228 void ParseData::Initialize() { | 283 void ParseData::Initialize() { |
| 229 // Prepares state for use. | 284 // Prepares state for use. |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 } | 977 } |
| 923 } | 978 } |
| 924 | 979 |
| 925 // Make sure the target stack is empty. | 980 // Make sure the target stack is empty. |
| 926 DCHECK(target_stack_ == NULL); | 981 DCHECK(target_stack_ == NULL); |
| 927 | 982 |
| 928 return result; | 983 return result; |
| 929 } | 984 } |
| 930 | 985 |
| 931 | 986 |
| 987 // This method is invoked by the runtime to re-parse the source of a lazily |
| 988 // compiled function when that function gets called. |
| 932 FunctionLiteral* Parser::ParseLazy() { | 989 FunctionLiteral* Parser::ParseLazy() { |
| 933 // It's OK to use the counters here, since this function is only called in | 990 // It's OK to use the counters here, since this function is only called in |
| 934 // the main thread. | 991 // the main thread. |
| 935 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 992 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 936 Handle<String> source(String::cast(script()->source())); | 993 Handle<String> source(String::cast(script()->source())); |
| 937 isolate()->counters()->total_parse_size()->Increment(source->length()); | 994 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 938 base::ElapsedTimer timer; | 995 base::ElapsedTimer timer; |
| 939 if (FLAG_trace_parse) { | 996 if (FLAG_trace_parse) { |
| 940 timer.Start(); | 997 timer.Start(); |
| 941 } | 998 } |
| (...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3601 // lazy compilation are: | 3658 // lazy compilation are: |
| 3602 // - It must not have been prohibited by the caller to Parse (some callers | 3659 // - It must not have been prohibited by the caller to Parse (some callers |
| 3603 // need a full AST). | 3660 // need a full AST). |
| 3604 // - The outer scope must allow lazy compilation of inner functions. | 3661 // - The outer scope must allow lazy compilation of inner functions. |
| 3605 // - The function mustn't be a function expression with an open parenthesis | 3662 // - The function mustn't be a function expression with an open parenthesis |
| 3606 // before; we consider that a hint that the function will be called | 3663 // before; we consider that a hint that the function will be called |
| 3607 // immediately, and it would be a waste of time to make it lazily | 3664 // immediately, and it would be a waste of time to make it lazily |
| 3608 // compiled. | 3665 // compiled. |
| 3609 // These are all things we can know at this point, without looking at the | 3666 // These are all things we can know at this point, without looking at the |
| 3610 // function itself. | 3667 // function itself. |
| 3611 | 3668 bool is_lazily_parsed = |
| 3612 // In addition, we need to distinguish between these cases: | 3669 (mode() != PARSE_EAGERLY && scope_->AllowsLazyCompilation() && |
| 3613 // (function foo() { | 3670 !parenthesized_function_); |
| 3614 // bar = function() { return 1; } | |
| 3615 // })(); | |
| 3616 // and | |
| 3617 // (function foo() { | |
| 3618 // var a = 1; | |
| 3619 // bar = function() { return a; } | |
| 3620 // })(); | |
| 3621 | |
| 3622 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume | |
| 3623 // parenthesis before the function means that it will be called | |
| 3624 // immediately). The inner function *must* be parsed eagerly to resolve the | |
| 3625 // possible reference to the variable in foo's scope. However, it's possible | |
| 3626 // that it will be compiled lazily. | |
| 3627 | |
| 3628 // To make this additional case work, both Parser and PreParser implement a | |
| 3629 // logic where only top-level functions will be parsed lazily. | |
| 3630 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
| 3631 scope_->AllowsLazyCompilation() && | |
| 3632 !parenthesized_function_); | |
| 3633 parenthesized_function_ = false; // The bit was set for this function only. | 3671 parenthesized_function_ = false; // The bit was set for this function only. |
| 3634 | 3672 |
| 3635 if (is_lazily_parsed) { | 3673 if (is_lazily_parsed) { |
| 3636 SkipLazyFunctionBody(function_name, &materialized_literal_count, | 3674 SkipLazyFunctionBody(function_name, &materialized_literal_count, |
| 3637 &expected_property_count, CHECK_OK); | 3675 &expected_property_count, CHECK_OK); |
| 3638 } else { | 3676 } else { |
| 3639 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | 3677 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, |
| 3640 is_generator, CHECK_OK); | 3678 is_generator, CHECK_OK); |
| 3641 materialized_literal_count = function_state.materialized_literal_count(); | 3679 materialized_literal_count = function_state.materialized_literal_count(); |
| 3642 expected_property_count = function_state.expected_property_count(); | 3680 expected_property_count = function_state.expected_property_count(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 | 3748 |
| 3711 scope_->set_end_position(entry.end_pos()); | 3749 scope_->set_end_position(entry.end_pos()); |
| 3712 Expect(Token::RBRACE, ok); | 3750 Expect(Token::RBRACE, ok); |
| 3713 if (!*ok) { | 3751 if (!*ok) { |
| 3714 return; | 3752 return; |
| 3715 } | 3753 } |
| 3716 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 3754 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3717 *materialized_literal_count = entry.literal_count(); | 3755 *materialized_literal_count = entry.literal_count(); |
| 3718 *expected_property_count = entry.property_count(); | 3756 *expected_property_count = entry.property_count(); |
| 3719 scope_->SetStrictMode(entry.strict_mode()); | 3757 scope_->SetStrictMode(entry.strict_mode()); |
| 3758 if (entry.calls_eval()) { |
| 3759 // If there is a direct call to eval (ES5 10.4.2(2) / 15.1.2.1.1) then |
| 3760 // every variable gets allocated and there's little point in keeping track |
| 3761 // of which variables are accessed by nested functions. |
| 3762 scope_->DeclarationScope()->RecordEvalCall(); |
| 3763 } else { |
| 3764 FunctionEntry::IdentifierIterator it = entry.Identifiers(); |
| 3765 while (!it.AtEnd()) { |
| 3766 ExpressionFromIdentifier(it.Next(ast_value_factory()), |
| 3767 RelocInfo::kNoPosition, scope_, factory()); |
| 3768 } |
| 3769 } |
| 3720 } else { | 3770 } else { |
| 3721 // With no cached data, we partially parse the function, without building an | 3771 // With no cached data, we partially parse the function, without building an |
| 3722 // AST. This gathers the data needed to build a lazy function. | 3772 // AST. This gathers the data needed to build a lazy function. |
| 3723 SingletonLogger logger; | 3773 SingletonLogger logger; |
| 3724 PreParser::PreParseResult result = | 3774 PreParser::PreParseResult result = |
| 3725 ParseLazyFunctionBodyWithPreParser(&logger); | 3775 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3726 if (result == PreParser::kPreParseStackOverflow) { | 3776 if (result == PreParser::kPreParseStackOverflow) { |
| 3727 // Propagate stack overflow. | 3777 // Propagate stack overflow. |
| 3728 set_stack_overflow(); | 3778 set_stack_overflow(); |
| 3729 *ok = false; | 3779 *ok = false; |
| 3730 return; | 3780 return; |
| 3731 } | 3781 } |
| 3732 if (logger.has_error()) { | 3782 if (logger.has_error()) { |
| 3733 ParserTraits::ReportMessageAt( | 3783 ParserTraits::ReportMessageAt( |
| 3734 Scanner::Location(logger.start(), logger.end()), | 3784 Scanner::Location(logger.start(), logger.end()), |
| 3735 logger.message(), logger.argument_opt(), logger.is_reference_error()); | 3785 logger.message(), logger.argument_opt(), logger.is_reference_error()); |
| 3736 *ok = false; | 3786 *ok = false; |
| 3737 return; | 3787 return; |
| 3738 } | 3788 } |
| 3739 scope_->set_end_position(logger.end()); | 3789 scope_->set_end_position(logger.end()); |
| 3740 Expect(Token::RBRACE, ok); | 3790 Expect(Token::RBRACE, ok); |
| 3741 if (!*ok) { | 3791 if (!*ok) { |
| 3742 return; | 3792 return; |
| 3743 } | 3793 } |
| 3794 |
| 3795 if (logger.calls_eval()) { |
| 3796 scope_->DeclarationScope()->RecordEvalCall(); |
| 3797 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3798 DCHECK(log_); |
| 3799 log_->LogEvalCall(); |
| 3800 } |
| 3801 } else { |
| 3802 SingletonLogger::IdentifierIterator it = logger.IdentifiersStart(); |
| 3803 for (const AstRawString* identifier = it.Next(); identifier != NULL; |
| 3804 identifier = it.Next()) { |
| 3805 // position doesn't matter here, we're only creating the expression |
| 3806 // so we can track usage of variables |
| 3807 ExpressionFromIdentifier(identifier, RelocInfo::kNoPosition, scope_, |
| 3808 factory()); |
| 3809 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3810 DCHECK(log_); |
| 3811 log_->LogIdentifier(identifier); |
| 3812 } |
| 3813 } |
| 3814 } |
| 3815 |
| 3744 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 3816 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3745 *materialized_literal_count = logger.literals(); | 3817 *materialized_literal_count = logger.literals(); |
| 3746 *expected_property_count = logger.properties(); | 3818 *expected_property_count = logger.properties(); |
| 3747 scope_->SetStrictMode(logger.strict_mode()); | 3819 scope_->SetStrictMode(logger.strict_mode()); |
| 3748 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3820 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3749 DCHECK(log_); | 3821 DCHECK(log_); |
| 3750 // Position right after terminal '}'. | 3822 // Position right after terminal '}'. |
| 3751 int body_end = scanner()->location().end_pos; | 3823 int body_end = scanner()->location().end_pos; |
| 3752 log_->LogFunction(function_block_pos, body_end, | 3824 log_->LogFunction(function_block_pos, body_end, |
| 3753 *materialized_literal_count, | 3825 *materialized_literal_count, |
| 3754 *expected_property_count, | 3826 *expected_property_count, |
| 3755 scope_->strict_mode()); | 3827 scope_->strict_mode()); |
| 3756 } | 3828 } |
| 3757 } | 3829 } |
| 3758 } | 3830 } |
| 3759 | 3831 |
| 3760 | 3832 |
| 3761 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3833 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3762 const AstRawString* function_name, int pos, Variable* fvar, | 3834 const AstRawString* function_name, int pos, Variable* fvar, |
| 3763 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3835 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3764 // Everything inside an eagerly parsed function will be parsed eagerly | 3836 // We can lazily parse functions enclosed in eagerly parsed functions but we |
| 3765 // (see comment above). | 3837 // have to keep track of what variables the inner functions access - or if the |
| 3766 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3838 // the inner function calls eval (in which case we have to assume every |
| 3839 // variable might be accessed inside the eval). |
| 3840 Mode mode = |
| 3841 (mode_ == PARSE_EAGERLY) ? PARSE_EAGERLY : PARSE_INNER_FUNCTION_LAZILY; |
| 3842 ParsingModeScope parsing_mode(this, mode); |
| 3843 |
| 3767 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3844 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3768 if (fvar != NULL) { | 3845 if (fvar != NULL) { |
| 3769 VariableProxy* fproxy = scope_->NewUnresolved( | 3846 VariableProxy* fproxy = scope_->NewUnresolved( |
| 3770 factory(), function_name, Interface::NewConst()); | 3847 factory(), function_name, Interface::NewConst()); |
| 3771 fproxy->BindTo(fvar); | 3848 fproxy->BindTo(fvar); |
| 3772 body->Add(factory()->NewExpressionStatement( | 3849 body->Add(factory()->NewExpressionStatement( |
| 3773 factory()->NewAssignment(fvar_init_op, | 3850 factory()->NewAssignment(fvar_init_op, |
| 3774 fproxy, | 3851 fproxy, |
| 3775 factory()->NewThisFunction(pos), | 3852 factory()->NewThisFunction(pos), |
| 3776 RelocInfo::kNoPosition), | 3853 RelocInfo::kNoPosition), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3820 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3897 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3821 SingletonLogger* logger) { | 3898 SingletonLogger* logger) { |
| 3822 // This function may be called on a background thread too; record only the | 3899 // This function may be called on a background thread too; record only the |
| 3823 // main thread preparse times. | 3900 // main thread preparse times. |
| 3824 if (pre_parse_timer_ != NULL) { | 3901 if (pre_parse_timer_ != NULL) { |
| 3825 pre_parse_timer_->Start(); | 3902 pre_parse_timer_->Start(); |
| 3826 } | 3903 } |
| 3827 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 3904 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 3828 | 3905 |
| 3829 if (reusable_preparser_ == NULL) { | 3906 if (reusable_preparser_ == NULL) { |
| 3830 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); | 3907 reusable_preparser_ = new PreParser(&scanner_, NULL, ast_value_factory(), |
| 3908 zone(), stack_limit_); |
| 3831 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3909 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3832 reusable_preparser_->set_allow_modules(allow_modules()); | 3910 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3833 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3911 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3834 reusable_preparser_->set_allow_lazy(true); | 3912 reusable_preparser_->set_allow_lazy(true); |
| 3835 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); | 3913 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); |
| 3836 reusable_preparser_->set_allow_harmony_numeric_literals( | 3914 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 3837 allow_harmony_numeric_literals()); | 3915 allow_harmony_numeric_literals()); |
| 3838 reusable_preparser_->set_allow_classes(allow_classes()); | 3916 reusable_preparser_->set_allow_classes(allow_classes()); |
| 3839 reusable_preparser_->set_allow_harmony_object_literals( | 3917 reusable_preparser_->set_allow_harmony_object_literals( |
| 3840 allow_harmony_object_literals()); | 3918 allow_harmony_object_literals()); |
| 3841 } | 3919 } |
| 3842 PreParser::PreParseResult result = | 3920 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 3843 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3921 strict_mode(), is_generator(), mode_ == PARSE_INNER_FUNCTION_LAZILY, |
| 3844 is_generator(), | 3922 logger); |
| 3845 logger); | |
| 3846 if (pre_parse_timer_ != NULL) { | 3923 if (pre_parse_timer_ != NULL) { |
| 3847 pre_parse_timer_->Stop(); | 3924 pre_parse_timer_->Stop(); |
| 3848 } | 3925 } |
| 3849 return result; | 3926 return result; |
| 3850 } | 3927 } |
| 3851 | 3928 |
| 3852 | 3929 |
| 3853 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3930 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3854 // CallRuntime :: | 3931 // CallRuntime :: |
| 3855 // '%' Identifier Arguments | 3932 // '%' Identifier Arguments |
| (...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4950 | 5027 |
| 4951 // We cannot internalize on a background thread; a foreground task will take | 5028 // We cannot internalize on a background thread; a foreground task will take |
| 4952 // care of calling Parser::Internalize just before compilation. | 5029 // care of calling Parser::Internalize just before compilation. |
| 4953 | 5030 |
| 4954 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 5031 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 4955 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 5032 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
| 4956 log_ = NULL; | 5033 log_ = NULL; |
| 4957 } | 5034 } |
| 4958 } | 5035 } |
| 4959 } } // namespace v8::internal | 5036 } } // namespace v8::internal |
| OLD | NEW |