Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Unified Diff: src/parser.cc

Issue 169223009: Add comments about lazy parsing and lazy compilation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 409059778a6a5f44606f6d0bed20af710cb797ec..54e57d5096618cb21485a12e5ace3401b25d06b2 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3973,8 +3973,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
scope_->DeclareFunctionVar(fvar_declaration);
}
- // Determine whether the function will be lazily compiled.
- // The heuristics are:
+ // Determine if the function can be parsed lazily. Lazy parsing is different
+ // from lazy compilation; we need to parse more eagerly than we compile.
+
+ // We can only parse lazily if we also compile lazily. The heuristics for
+ // lazy compilation are:
// - It must not have been prohibited by the caller to Parse (some callers
// need a full AST).
// - The outer scope must allow lazy compilation of inner functions.
@@ -3984,12 +3987,31 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// compiled.
// These are all things we can know at this point, without looking at the
// function itself.
- bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
- scope_->AllowsLazyCompilation() &&
- !parenthesized_function_);
+
+ // In addition, we need to distinguish between these cases:
+ // (function foo() {
+ // bar = function() { return 1; }
+ // })();
+ // and
+ // (function foo() {
+ // var a = 1;
+ // bar = function() { return a; }
+ // })();
+
+ // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
+ // parenthesis before the function means that it will be called
+ // immediately). The inner function *must* be parsed eagerly to resolve the
+ // possible reference to the variable in foo's scope. However, it's possible
+ // that it will be compiled lazily.
+
+ // To make this additional case work, both Parser and PreParser implement a
+ // logic where only top-level functions will be parsed lazily.
+ bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
+ scope_->AllowsLazyCompilation() &&
+ !parenthesized_function_);
parenthesized_function_ = false; // The bit was set for this function only.
- if (is_lazily_compiled) {
+ if (is_lazily_parsed) {
int function_block_pos = position();
FunctionEntry entry;
if (pre_parse_data_ != NULL) {
@@ -4013,7 +4035,20 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
expected_property_count = entry.property_count();
scope_->SetLanguageMode(entry.language_mode());
} else {
- is_lazily_compiled = false;
+ // This case happens when we have preparse data but it doesn't contain
+ // an entry for the function. As a safety net, fall back to eager
+ // parsing. It is unclear whether PreParser's laziness analysis can
+ // produce different results than the Parser's laziness analysis (see
+ // https://codereview.chromium.org/7565003 ). This safety net is
+ // guarding against the case where Parser thinks a function should be
+ // lazily parsed, but PreParser thinks it should be eagerly parsed --
+ // in that case we fall back to eager parsing in Parser, too. Note
+ // that the opposite case is worse: if PreParser thinks a function
+ // should be lazily parsed, but Parser thinks it should be eagerly
+ // parsed, it will never advance the preparse data beyond that
+ // function and all further laziness will fail (all functions will be
+ // parsed eagerly).
+ is_lazily_parsed = false;
}
} else {
// With no preparser data, we partially parse the function, without
@@ -4050,7 +4085,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
}
}
- if (!is_lazily_compiled) {
+ if (!is_lazily_parsed) {
+ // Everything inside an eagerly parsed function will be parsed eagerly
+ // (see comment above).
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
body = new(zone()) ZoneList<Statement*>(8, zone());
if (fvar != NULL) {
« no previous file with comments | « no previous file | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698