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

Unified Diff: src/preparser.h

Issue 641283003: Support lazy parsing of inner functions (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: Actually track variable declarations in the preparser Created 6 years, 1 month 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 | « src/preparse-data-format.h ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index fd82651a7e012a88c7e09c58c53732522853d121..57a93d8d4d183463d0797e76f3c933c1072c1333 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -13,6 +13,7 @@
#include "src/scanner.h"
#include "src/scopes.h"
#include "src/token.h"
+#include "src/zone.h"
namespace v8 {
namespace internal {
@@ -42,7 +43,6 @@ namespace internal {
// // Used by FunctionState and BlockState.
// typedef Scope;
// typedef GeneratorVariable;
-// typedef Zone;
// // Return types for traversing functions.
// typedef Identifier;
// typedef Expression;
@@ -69,7 +69,7 @@ class ParserBase : public Traits {
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
- ParserRecorder* log, typename Traits::Type::Zone* zone,
+ ParserRecorder* log, Zone* zone,
typename Traits::Type::Parser this_object)
: Traits(this_object),
parenthesized_function_(false),
@@ -126,10 +126,7 @@ class ParserBase : public Traits {
kDontAllowEvalOrArguments
};
- enum Mode {
- PARSE_LAZILY,
- PARSE_EAGERLY
- };
+ enum Mode { PARSE_LAZILY, PARSE_EAGERLY, PARSE_INNER_FUNCTION_LAZILY };
class Checkpoint;
class ObjectLiteralChecker;
@@ -217,7 +214,6 @@ class ParserBase : public Traits {
FunctionState* outer_function_state_;
typename Traits::Type::Scope** scope_stack_;
typename Traits::Type::Scope* outer_scope_;
- typename Traits::Type::Zone* extra_param_;
typename Traits::Type::Factory* factory_;
friend class ParserTraits;
@@ -274,7 +270,7 @@ class ParserBase : public Traits {
bool stack_overflow() const { return stack_overflow_; }
void set_stack_overflow() { stack_overflow_ = true; }
Mode mode() const { return mode_; }
- typename Traits::Type::Zone* zone() const { return zone_; }
+ Zone* zone() const { return zone_; }
INLINE(Token::Value peek()) {
if (stack_overflow_) return Token::ILLEGAL;
@@ -576,7 +572,7 @@ class ParserBase : public Traits {
bool allow_arrow_functions_;
bool allow_harmony_object_literals_;
- typename Traits::Type::Zone* zone_; // Only used by Parser.
+ Zone* zone_;
};
@@ -934,12 +930,27 @@ class PreParserStatementList {
class PreParserScope {
public:
- explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type,
- void* = NULL)
- : scope_type_(scope_type) {
+ PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, Zone* zone,
+ bool log_identifiers)
+ : outer_scope_(outer_scope),
+ scope_type_(scope_type),
+ zone_(zone),
+ declared_variables_(NULL),
+ unbound_variables_(NULL) {
strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
+ if (log_identifiers) {
+ ZoneAllocationPolicy allocator(zone);
+ declared_variables_ = new (zone->New(sizeof(ZoneHashMap)))
+ ZoneHashMap(ZoneHashMap::PointersMatch,
+ ZoneHashMap::kDefaultHashMapCapacity, allocator);
+ unbound_variables_ = new (zone->New(sizeof(ZoneHashMap)))
+ ZoneHashMap(ZoneHashMap::PointersMatch,
+ ZoneHashMap::kDefaultHashMapCapacity, allocator);
+ }
}
+ ~PreParserScope();
+
ScopeType type() { return scope_type_; }
StrictMode strict_mode() const { return strict_mode_; }
void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
@@ -957,12 +968,44 @@ class PreParserScope {
void RecordArgumentsUsage() {}
void RecordThisUsage() {}
+ bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
+ bool is_function_scope() const {
+ return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE;
+ }
+ bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
+ bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; }
+ bool is_declaration_scope() const {
+ return is_eval_scope() || is_function_scope() || is_module_scope() ||
+ is_global_scope();
+ }
+
+ // The scope immediately surrounding this scope, or NULL.
+ PreParserScope* outer_scope() const { return outer_scope_; }
+
+ // Walk up the scope chain and return the scope where var declarations will be
+ // hoisted to (could be this).
+ PreParserScope* DeclarationScope();
+
+ // Record a variable declaration in the current declaration scope
+ void Declare(const AstRawString* identifier, bool lexical = false);
+
+ // Record the usage of a variable in an identifier expression. If the variable
+ // was not declared in this scope, we report it to the full parser so it will
+ // be context-allocated.
+ void RecordVariableUsage(const AstRawString* identifier);
+
+ void LogUnboundVariables(ParserRecorder* recorder);
+
// Allow scope->Foo() to work.
PreParserScope* operator->() { return this; }
private:
+ PreParserScope* outer_scope_;
ScopeType scope_type_;
StrictMode strict_mode_;
+ Zone* zone_;
+ ZoneHashMap* declared_variables_;
+ ZoneHashMap* unbound_variables_;
};
@@ -1111,13 +1154,11 @@ class PreParserTraits {
// Used by FunctionState and BlockState.
typedef PreParserScope Scope;
- typedef PreParserScope ScopePtr;
+ typedef PreParserScope ScopePtr; // Return type of NewScope()
inline static Scope* ptr_to_scope(ScopePtr& scope) { return &scope; }
// PreParser doesn't need to store generator variables.
typedef void GeneratorVariable;
- // No interaction with Zones.
- typedef void Zone;
typedef int AstProperties;
typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
@@ -1210,9 +1251,10 @@ class PreParserTraits {
static void CheckAssigningFunctionLiteralToProperty(
PreParserExpression left, PreParserExpression right) {}
- // PreParser doesn't need to keep track of eval calls.
- static void CheckPossibleEvalCall(PreParserExpression expression,
- PreParserScope* scope) {}
+ // Need to record direct calls to eval so every variable in the enclosing
+ // scope gets allocated
+ void CheckPossibleEvalCall(PreParserExpression expression,
+ PreParserScope* scope);
static PreParserExpression MarkExpressionAsAssigned(
PreParserExpression expression) {
@@ -1221,6 +1263,8 @@ class PreParserTraits {
return expression;
}
+ void RecordCurrentSymbolAsIdentifierExpression();
+
bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
PreParserExpression y,
Token::Value op,
@@ -1246,9 +1290,8 @@ class PreParserTraits {
const char* type, Handle<Object> arg, int pos) {
return PreParserExpression::Default();
}
- PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) {
- return PreParserScope(outer_scope, scope_type);
- }
+ inline PreParserScope NewScope(PreParserScope* outer_scope,
+ ScopeType scope_type);
// Reporting errors.
void ReportMessageAt(Scanner::Location location,
@@ -1339,15 +1382,15 @@ class PreParserTraits {
return PreParserExpression::Default();
}
- static PreParserExpressionList NewExpressionList(int size, void* zone) {
+ static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
return PreParserExpressionList();
}
- static PreParserStatementList NewStatementList(int size, void* zone) {
+ static PreParserStatementList NewStatementList(int size, Zone* zone) {
return PreParserStatementList();
}
- static PreParserExpressionList NewPropertyList(int size, void* zone) {
+ static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
return PreParserExpressionList();
}
@@ -1412,16 +1455,20 @@ class PreParser : public ParserBase<PreParserTraits> {
kPreParseSuccess
};
- PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
- : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
- this) {}
+ PreParser(Scanner* scanner, ParserRecorder* log,
+ AstValueFactory* ast_value_factory, Zone* zone,
+ uintptr_t stack_limit)
+ : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, zone,
+ this),
+ ast_value_factory_(ast_value_factory),
+ log_identifiers_(false) {}
// Pre-parse the program from the character stream; returns true on
// success (even if parsing failed, the pre-parse data successfully
// captured the syntax error), and false if a stack-overflow happened
// during parsing.
PreParseResult PreParseProgram() {
- PreParserScope scope(scope_, GLOBAL_SCOPE);
+ PreParserScope scope = NewScope(scope_, GLOBAL_SCOPE);
PreParserFactory factory(NULL);
FunctionState top_scope(&function_state_, &scope_, &scope, &factory);
bool ok = true;
@@ -1444,8 +1491,8 @@ class PreParser : public ParserBase<PreParserTraits> {
// keyword and parameters, and have consumed the initial '{'.
// At return, unless an error occurred, the scanner is positioned before the
// the final '}'.
- PreParseResult PreParseLazyFunction(StrictMode strict_mode,
- bool is_generator,
+ PreParseResult PreParseLazyFunction(StrictMode strict_mode, bool is_generator,
+ bool log_identifiers,
ParserRecorder* log);
private:
@@ -1521,7 +1568,14 @@ class PreParser : public ParserBase<PreParserTraits> {
FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok);
+ PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) {
+ return PreParserScope(outer_scope, scope_type, zone(), log_identifiers_);
+ }
+
bool CheckInOrOf(bool accept_OF);
+
+ AstValueFactory* ast_value_factory_;
+ bool log_identifiers_;
};
@@ -1546,6 +1600,12 @@ PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
}
+PreParserScope PreParserTraits::NewScope(PreParserScope* outer_scope,
+ ScopeType scope_type) {
+ return pre_parser_->NewScope(outer_scope, scope_type);
+}
+
+
template <class Traits>
ParserBase<Traits>::FunctionState::FunctionState(
FunctionState** function_state_stack,
@@ -1767,6 +1827,7 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
case Token::FUTURE_STRICT_RESERVED_WORD: {
// Using eval or arguments in this context is OK even in strict mode.
IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
+ this->RecordCurrentSymbolAsIdentifierExpression();
result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
break;
}
@@ -2018,6 +2079,7 @@ typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
} else if (!in_class && allow_harmony_object_literals_ &&
Token::IsIdentifier(name_token, strict_mode(),
this->is_generator())) {
+ this->RecordCurrentSymbolAsIdentifierExpression();
value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
} else {
« no previous file with comments | « src/preparse-data-format.h ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698