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 |