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

Unified Diff: src/preparser.cc

Issue 641283003: Support lazy parsing of inner functions (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: 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/preparser.h ('k') | src/vector.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index 987900a20d5844ebfef3e17d93fcd4c43f9503ea..84177513d7b2a463f229a217beeed54b674735ef 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -11,6 +11,7 @@
#include "src/globals.h"
#include "src/hashmap.h"
#include "src/list.h"
+#include "src/parser.h"
#include "src/preparse-data.h"
#include "src/preparse-data-format.h"
#include "src/preparser.h"
@@ -20,6 +21,79 @@
namespace v8 {
namespace internal {
+PreParserScope::~PreParserScope() {
+ if (unbound_variables_ && outer_scope_) {
+ PreParserScope* scope = outer_scope_->DeclarationScope();
+ for (ZoneHashMap::Entry* p = unbound_variables_->Start(); p != NULL;
+ p = unbound_variables_->Next(p)) {
+ AstRawString* identifier = static_cast<AstRawString*>(p->key);
+ if (!declared_variables_->Lookup(identifier, identifier->hash(), false,
+ ZoneAllocationPolicy(zone_))) {
+ scope->RecordVariableUsage(identifier);
+ }
+ }
+ }
+}
+
+
+PreParserScope* PreParserScope::DeclarationScope() {
+ PreParserScope* scope = this;
+ while (!scope->is_declaration_scope()) {
+ scope = scope->outer_scope();
+ }
+ return scope;
+}
+
+
+void PreParserScope::RecordVariableUsage(const AstRawString* identifier) {
+ if (is_declaration_scope()) {
+ ZoneAllocationPolicy allocator(zone_);
+ if (!declared_variables_->Lookup(const_cast<AstRawString*>(identifier),
+ identifier->hash(), false, allocator)) {
+ unbound_variables_->Lookup(const_cast<AstRawString*>(identifier),
+ identifier->hash(), true, allocator);
+ }
+ } else {
+ DeclarationScope()->Declare(identifier);
rossberg 2014/11/06 11:55:46 Why Declare here?
+ }
+}
+
+
+void PreParserScope::LogUnboundVariables(ParserRecorder* recorder) {
+ for (ZoneHashMap::Entry* p = unbound_variables_->Start(); p != NULL;
+ p = unbound_variables_->Next(p)) {
+ AstRawString* identifier = static_cast<AstRawString*>(p->key);
+ if (!declared_variables_->Lookup(identifier, identifier->hash(), false,
+ ZoneAllocationPolicy(zone_))) {
+ recorder->LogIdentifier(identifier);
+ }
+ }
+ unbound_variables_->Clear();
+}
+
+
+void PreParserScope::Declare(const AstRawString* identifier) {
+ if (is_declaration_scope()) {
+ DCHECK(declared_variables_);
+ declared_variables_->Lookup(const_cast<AstRawString*>(identifier),
+ identifier->hash(), true,
+ ZoneAllocationPolicy(zone_));
+ } else {
+ DeclarationScope()->Declare(identifier);
+ }
+}
+
+
+void PreParserTraits::RecordCurrentSymbolAsIdentifierExpression() {
+ if (pre_parser_->log_ != NULL && pre_parser_->log_identifiers_) {
+ DCHECK(pre_parser_->ast_value_factory_ != NULL);
+ const AstRawString* identifier =
+ pre_parser_->scanner()->CurrentSymbol(pre_parser_->ast_value_factory_);
+ pre_parser_->scope_->RecordVariableUsage(identifier);
+ }
+}
+
+
void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* message,
const char* arg,
@@ -42,6 +116,15 @@ void PreParserTraits::ReportMessageAt(int start_pos,
}
+void PreParserTraits::CheckPossibleEvalCall(PreParserExpression expression,
+ PreParserScope* scope) {
+ if (pre_parser_->log_ != NULL && pre_parser_->log_identifiers_ &&
+ expression.IsIdentifier() && expression.AsIdentifier().IsEval()) {
+ pre_parser_->log_->LogEvalCall();
+ }
+}
+
+
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
return PreParserIdentifier::FutureReserved();
@@ -100,14 +183,16 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral(
PreParser::PreParseResult PreParser::PreParseLazyFunction(
- StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
+ StrictMode strict_mode, bool is_generator, bool log_identifiers,
+ ParserRecorder* log) {
+ log_identifiers_ = log_identifiers;
log_ = log;
// Lazy functions always have trivial outer scopes (no with/catch scopes).
- PreParserScope top_scope(scope_, GLOBAL_SCOPE);
+ PreParserScope top_scope = NewScope(NULL, GLOBAL_SCOPE);
PreParserFactory top_factory(NULL);
FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
scope_->SetStrictMode(strict_mode);
- PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+ PreParserScope function_scope = NewScope(scope_, FUNCTION_SCOPE);
PreParserFactory function_factory(NULL);
FunctionState function_state(&function_state_, &scope_, &function_scope,
&function_factory);
@@ -459,6 +544,12 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
// Parse variable name.
if (nvars > 0) Consume(Token::COMMA);
ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
+ if (log_identifiers_) {
+ DCHECK(ast_value_factory_);
+ const AstRawString* identifier =
+ scanner()->CurrentSymbol(ast_value_factory_);
+ scope_->Declare(identifier);
+ }
nvars++;
if (peek() == Token::ASSIGN || require_initializer) {
Expect(Token::ASSIGN, CHECK_OK);
@@ -593,7 +684,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- PreParserScope with_scope(scope_, WITH_SCOPE);
+ PreParserScope with_scope = NewScope(scope_, WITH_SCOPE);
BlockState block_state(&scope_, &with_scope);
ParseStatement(CHECK_OK);
return Statement::Default();
@@ -767,7 +858,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
{
- PreParserScope with_scope(scope_, WITH_SCOPE);
+ PreParserScope with_scope = NewScope(scope_, WITH_SCOPE);
BlockState block_state(&scope_, &with_scope);
ParseBlock(CHECK_OK);
}
@@ -812,7 +903,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Parse function body.
ScopeType outer_scope_type = scope_->type();
- PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+ PreParserScope function_scope = NewScope(scope_, FUNCTION_SCOPE);
PreParserFactory factory(NULL);
FunctionState function_state(&function_state_, &scope_, &function_scope,
&factory);
@@ -915,6 +1006,9 @@ void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
// Position right after terminal '}'.
DCHECK_EQ(Token::RBRACE, scanner()->peek());
int body_end = scanner()->peek_location().end_pos;
+ if (log_identifiers_) {
+ scope_->LogUnboundVariables(log_);
+ }
log_->LogFunction(body_start, body_end,
function_state_->materialized_literal_count(),
function_state_->expected_property_count(),
« no previous file with comments | « src/preparser.h ('k') | src/vector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698