| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index aebcc9ae2ca069e2a84da3f9ed545d78bd83adee..2674929c75fa0f13fa39f205b3d4f7909636a6af 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -877,12 +877,30 @@ class ParserLog BASE_EMBEDDED {
|
| virtual int function_position() { return 0; }
|
| virtual int symbol_position() { return 0; }
|
| virtual int symbol_ids() { return 0; }
|
| + virtual void PauseRecording() {}
|
| + virtual void ResumeRecording() {}
|
| virtual Vector<unsigned> ExtractData() {
|
| return Vector<unsigned>();
|
| };
|
| };
|
|
|
|
|
| +
|
| +class ConditionalLogPauseScope {
|
| + public:
|
| + ConditionalLogPauseScope(bool pause, ParserLog* log)
|
| + : log_(log), pause_(pause) {
|
| + if (pause) log->PauseRecording();
|
| + }
|
| + ~ConditionalLogPauseScope() {
|
| + if (pause_) log_->ResumeRecording();
|
| + }
|
| + private:
|
| + ParserLog* log_;
|
| + bool pause_;
|
| +};
|
| +
|
| +
|
| class AstBuildingParserFactory : public ParserFactory {
|
| public:
|
| explicit AstBuildingParserFactory(int expected_symbols)
|
| @@ -970,15 +988,31 @@ class PartialParserRecorder: public ParserLog {
|
| return data;
|
| }
|
|
|
| + virtual void PauseRecording() {
|
| + pause_count_++;
|
| + is_recording_ = false;
|
| + }
|
| +
|
| + virtual void ResumeRecording() {
|
| + ASSERT(pause_count_ > 0);
|
| + if (--pause_count_ == 0) is_recording_ = !has_error();
|
| + }
|
| +
|
| protected:
|
| bool has_error() {
|
| return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
|
| }
|
| + bool is_recording() {
|
| + return is_recording_;
|
| + }
|
|
|
| void WriteString(Vector<const char> str);
|
|
|
| Collector<unsigned> function_store_;
|
| unsigned preamble_[ScriptDataImpl::kHeaderSize];
|
| + bool is_recording_;
|
| + int pause_count_;
|
| +
|
| #ifdef DEBUG
|
| int prev_start;
|
| #endif
|
| @@ -991,6 +1025,7 @@ class CompleteParserRecorder: public PartialParserRecorder {
|
| CompleteParserRecorder();
|
|
|
| virtual void LogSymbol(int start, Vector<const char> literal) {
|
| + if (!is_recording_) return;
|
| int hash = vector_hash(literal);
|
| HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
|
| int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
|
| @@ -1061,13 +1096,6 @@ class CompleteParserRecorder: public PartialParserRecorder {
|
| };
|
|
|
|
|
| -void ScriptDataImpl::SkipFunctionEntry(int start) {
|
| - ASSERT(function_index_ + FunctionEntry::kSize <= store_.length());
|
| - ASSERT(static_cast<int>(store_[function_index_]) == start);
|
| - function_index_ += FunctionEntry::kSize;
|
| -}
|
| -
|
| -
|
| FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
|
| // The current pre-data entry must be a FunctionEntry with the given
|
| // start position.
|
| @@ -1126,7 +1154,10 @@ bool ScriptDataImpl::SanityCheck() {
|
|
|
|
|
|
|
| -PartialParserRecorder::PartialParserRecorder() : function_store_(0) {
|
| +PartialParserRecorder::PartialParserRecorder()
|
| + : function_store_(0),
|
| + is_recording_(true),
|
| + pause_count_(0) {
|
| preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
|
| preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
|
| preamble_[ScriptDataImpl::kHasErrorOffset] = false;
|
| @@ -1202,6 +1233,7 @@ void PartialParserRecorder::LogMessage(Scanner::Location loc,
|
| for (int i = 0; i < args.length(); i++) {
|
| WriteString(CStrVector(args[i]));
|
| }
|
| + is_recording_ = false;
|
| }
|
|
|
|
|
| @@ -1248,7 +1280,7 @@ FunctionEntry PartialParserRecorder::LogFunction(int start) {
|
| ASSERT(start > prev_start);
|
| prev_start = start;
|
| #endif
|
| - if (has_error()) return FunctionEntry();
|
| + if (!is_recording_) return FunctionEntry();
|
| FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0));
|
| result.set_start_pos(start);
|
| return result;
|
| @@ -1343,6 +1375,8 @@ Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type,
|
| bool inside_with) {
|
| ASSERT(parent != NULL);
|
| parent->type_ = type;
|
| + // Initialize function is hijacked by DummyScope to increment scope depth.
|
| + parent->Initialize(inside_with);
|
| return parent;
|
| }
|
|
|
| @@ -1415,6 +1449,7 @@ class LexicalScope BASE_EMBEDDED {
|
| }
|
|
|
| ~LexicalScope() {
|
| + parser_->top_scope_->Leave();
|
| parser_->top_scope_ = prev_scope_;
|
| parser_->with_nesting_level_ = prev_level_;
|
| }
|
| @@ -1480,7 +1515,8 @@ bool Parser::PreParseProgram(Handle<String> source,
|
| NoHandleAllocation no_handle_allocation;
|
| scanner_.Initialize(source, stream, JAVASCRIPT);
|
| ASSERT(target_stack_ == NULL);
|
| - mode_ = PARSE_EAGERLY;
|
| + mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
|
| + if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
|
| DummyScope top_scope;
|
| LexicalScope scope(this, &top_scope);
|
| TemporaryScope temp_scope(this);
|
| @@ -1658,7 +1694,10 @@ void Parser::ReportMessage(const char* type, Vector<const char*> args) {
|
|
|
|
|
| Handle<String> Parser::GetSymbol(bool* ok) {
|
| - log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
|
| + if (is_pre_parsing_) {
|
| + log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
|
| + return Handle<String>::null();
|
| + }
|
| int symbol_id = -1;
|
| if (pre_data() != NULL) {
|
| symbol_id = pre_data()->GetSymbolIdentifier();
|
| @@ -1971,7 +2010,7 @@ void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
|
| }
|
|
|
| // Propagate the collected information on this property assignments.
|
| - if (top_scope_->is_function_scope()) {
|
| + if (!is_pre_parsing_ && top_scope_->is_function_scope()) {
|
| bool only_simple_this_property_assignments =
|
| this_property_assignment_finder.only_simple_this_property_assignments()
|
| && top_scope_->declarations()->length() == 0;
|
| @@ -4123,8 +4162,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
| int num_parameters = 0;
|
| // Parse function body.
|
| - { Scope::Type type = Scope::FUNCTION_SCOPE;
|
| - Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
|
| + { Scope* scope =
|
| + factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
|
| LexicalScope lexical_scope(this, scope);
|
| TemporaryScope temp_scope(this);
|
| top_scope_->SetScopeName(name);
|
| @@ -4155,7 +4194,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
| // NOTE: We create a proxy and resolve it here so that in the
|
| // future we can change the AST to only refer to VariableProxies
|
| // instead of Variables and Proxis as is the case now.
|
| - if (!function_name.is_null() && function_name->length() > 0) {
|
| + if (!is_pre_parsing_
|
| + && !function_name.is_null()
|
| + && function_name->length() > 0) {
|
| Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
|
| VariableProxy* fproxy =
|
| top_scope_->NewUnresolved(function_name, inside_with());
|
| @@ -4189,22 +4230,18 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
| }
|
| Counters::total_preparse_skipped.Increment(end_pos - function_block_pos);
|
| scanner_.SeekForward(end_pos);
|
| - pre_data()->Skip(entry.predata_function_skip(),
|
| - entry.predata_symbol_skip());
|
| materialized_literal_count = entry.literal_count();
|
| expected_property_count = entry.property_count();
|
| only_simple_this_property_assignments = false;
|
| this_property_assignments = Factory::empty_fixed_array();
|
| Expect(Token::RBRACE, CHECK_OK);
|
| } else {
|
| - if (pre_data() != NULL) {
|
| - // Skip pre-data entry for non-lazily compiled function.
|
| - pre_data()->SkipFunctionEntry(function_block_pos);
|
| + FunctionEntry entry;
|
| + if (is_lazily_compiled) entry = log()->LogFunction(function_block_pos);
|
| + {
|
| + ConditionalLogPauseScope pause_if(is_lazily_compiled, log());
|
| + ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
|
| }
|
| - FunctionEntry entry = log()->LogFunction(function_block_pos);
|
| - int predata_function_position_before = log()->function_position();
|
| - int predata_symbol_position_before = log()->symbol_position();
|
| - ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
|
| materialized_literal_count = temp_scope.materialized_literal_count();
|
| expected_property_count = temp_scope.expected_property_count();
|
| only_simple_this_property_assignments =
|
| @@ -4214,13 +4251,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
| Expect(Token::RBRACE, CHECK_OK);
|
| end_pos = scanner_.location().end_pos;
|
| if (entry.is_valid()) {
|
| + ASSERT(is_lazily_compiled);
|
| + ASSERT(is_pre_parsing_);
|
| entry.set_end_pos(end_pos);
|
| entry.set_literal_count(materialized_literal_count);
|
| entry.set_property_count(expected_property_count);
|
| - entry.set_predata_function_skip(
|
| - log()->function_position() - predata_function_position_before);
|
| - entry.set_predata_symbol_skip(
|
| - log()->symbol_position() - predata_symbol_position_before);
|
| }
|
| }
|
|
|
| @@ -5625,8 +5660,6 @@ FunctionLiteral* MakeLazyAST(Handle<Script> script,
|
| return result;
|
| }
|
|
|
| -
|
| #undef NEW
|
|
|
| -
|
| } } // namespace v8::internal
|
|
|