Reviewers: wingo, rossberg,
Message:
Andreas, it is not clear how to fix the strong mode todo I added in
ParseSuperExpression.
Andy, did the lexical this CL land? If so I think super.prop in arrows
should
work now. I'll add tests if that is the case.
Description:
[es6] Make ParseSuperExpression uses scopes instead
Previously it was using the FunctionState which does not work
correctly for lazy arrow functions.
To get this to work I had to fix some issues with some Scopes not
setting the function kind correctly.
Also, this removes innner_uses_super since we can track that on the
correct scope directly.
BUG=v8:4031
LOG=N
[email protected], [email protected]
Please review this at https://codereview.chromium.org/1092503003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+34, -36 lines):
M src/ast.cc
M src/parser.cc
M src/preparser.h
M src/preparser.cc
M src/scopes.cc
M test/cctest/test-parsing.cc
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index
5038716003e80125c1ff1fd1b3709443a0a3ea63..1d564f3849794f64378d828d5fe91ee064d21cdc
100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -179,7 +179,7 @@ LanguageMode FunctionLiteral::language_mode() const {
bool FunctionLiteral::uses_super_property() const {
DCHECK_NOT_NULL(scope());
- return scope()->uses_super_property() ||
scope()->inner_uses_super_property();
+ return scope()->uses_super_property();
}
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
9507b69df6f0d661c4c5f5933882dc897233b2ad..4301f4648326fc5009698bf707d9a7827841e31d
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1128,7 +1128,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate,
ParseInfo* info,
bool ok = true;
if (shared_info->is_arrow()) {
- Scope* scope = NewScope(scope_, ARROW_SCOPE);
+ Scope* scope =
+ NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
scope->set_start_position(shared_info->start_position());
FormalParameterErrorLocations error_locs;
bool has_rest = false;
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index
950f7b50ec35ca6a255788dac4b1aecccdef9086..024c916488951b5f85d573ab928e98742ed0d4f9
100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -107,7 +107,7 @@ PreParser::PreParseResult
PreParser::PreParseLazyFunction(
FunctionState top_state(&function_state_, &scope_, top_scope,
kNormalFunction,
&top_factory);
scope_->SetLanguageMode(language_mode);
- Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE);
+ Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
PreParserFactory function_factory(NULL);
FunctionState function_state(&function_state_, &scope_, function_scope,
kind,
&function_factory);
@@ -982,7 +982,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Parse function body.
bool outer_is_script_scope = scope_->is_script_scope();
- Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE);
+ Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
PreParserFactory factory(NULL);
FunctionState function_state(&function_state_, &scope_, function_scope,
kind,
&factory);
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index
36320513adb872f5ef4f51d450551af9ab1499d8..057a730bfec81d024440cb2866f92cc0a6296d17
100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -345,12 +345,17 @@ class ParserBase : public Traits {
Mode old_mode_;
};
- Scope* NewScope(Scope* parent, ScopeType scope_type,
- FunctionKind kind = kNormalFunction) {
+ Scope* NewScope(Scope* parent, ScopeType scope_type) {
+ DCHECK(scope_type != FUNCTION_SCOPE && scope_type != ARROW_SCOPE);
+ return NewScope(parent, scope_type, kNormalFunction);
+ }
+
+ Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
DCHECK(ast_value_factory());
DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
- DCHECK((scope_type == FUNCTION_SCOPE && IsValidFunctionKind(kind)) ||
- kind == kNormalFunction);
+ // DCHECK((scope_type == FUNCTION_SCOPE && IsValidFunctionKind(kind)) |
|
+ // kind == kNormalFunction);
+ DCHECK(scope_type == ARROW_SCOPE ? IsArrowFunction(kind) : true);
Scope* result = new (zone())
Scope(zone(), parent, scope_type, ast_value_factory(), kind);
result->Initialize();
@@ -2173,7 +2178,8 @@
ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
Consume(Token::LPAREN);
if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) {
// As a primary expression, the only thing that can follow "()"
is "=>".
- Scope* scope = this->NewScope(scope_, ARROW_SCOPE);
+ Scope* scope =
+ this->NewScope(scope_, ARROW_SCOPE,
FunctionKind::kArrowFunction);
scope->set_start_position(beg_pos);
FormalParameterErrorLocations error_locs;
bool has_rest = false;
@@ -2654,7 +2660,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool
accept_IN,
FormalParameterErrorLocations error_locs;
Scanner::Location loc(lhs_location.beg_pos,
scanner()->location().end_pos);
bool has_rest = false;
- Scope* scope = this->NewScope(scope_, ARROW_SCOPE);
+ Scope* scope =
+ this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
scope->set_start_position(lhs_location.beg_pos);
this->ParseArrowFunctionFormalParameters(scope, expression, loc,
&error_locs, &has_rest,
CHECK_OK);
@@ -3251,19 +3258,20 @@ ParserBase<Traits>::ParseSuperExpression(bool
is_new,
bool* ok) {
Expect(Token::SUPER, CHECK_OK);
- // TODO(wingo): Does this actually work with lazily compiled arrows?
- FunctionState* function_state = function_state_;
- while (IsArrowFunction(function_state->kind())) {
- function_state = function_state->outer();
+ Scope* scope = scope_->DeclarationScope();
+
+ while (scope->is_eval_scope() || scope->is_arrow_scope()) {
+ scope = scope->outer_scope();
+ DCHECK_NOT_NULL(scope);
+ scope = scope->DeclarationScope();
}
- // TODO(arv): Handle eval scopes similarly.
- FunctionKind kind = function_state->kind();
+ FunctionKind kind = scope->function_kind();
if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
i::IsConstructor(kind)) {
if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
- scope_->RecordSuperPropertyUsage();
- return this->SuperReference(scope_, factory());
+ scope->RecordSuperPropertyUsage();
+ return this->SuperReference(scope, factory());
}
// new super() is never allowed.
// super() is only allowed in derived constructor
@@ -3274,8 +3282,9 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
*ok = false;
return this->EmptyExpression();
}
- function_state->set_super_location(scanner()->location());
- return this->SuperReference(scope_, factory());
+ // TODO(rossberg): We might not have a FunctionState for the method
here.
+ // function_state->set_super_location(scanner()->location());
+ return this->SuperReference(scope, factory());
}
}
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index
d34d2e934c89d383995291a83e25e1f92f620430..cdf4b87aebc4900ce2d576c7277cd61246bec7bc
100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -174,7 +174,6 @@ void Scope::SetDefaults(ScopeType scope_type, Scope*
outer_scope,
inner_scope_calls_eval_ = false;
inner_scope_uses_arguments_ = false;
inner_scope_uses_this_ = false;
- inner_scope_uses_super_property_ = false;
force_eager_compilation_ = false;
force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
? outer_scope->has_forced_context_allocation() : false;
@@ -934,8 +933,6 @@ void Scope::Print(int n) {
if (inner_scope_uses_arguments_) {
Indent(n1, "// inner scope uses 'arguments'\n");
}
- if (inner_scope_uses_super_property_)
- Indent(n1, "// inner scope uses 'super' property\n");
if (inner_scope_uses_this_) Indent(n1, "// inner scope uses 'this'\n");
if (outer_scope_calls_sloppy_eval_) {
Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
@@ -1296,10 +1293,6 @@ void Scope::PropagateScopeInfo(bool
outer_scope_calls_sloppy_eval ) {
if (inner->scope_uses_arguments_ ||
inner->inner_scope_uses_arguments_) {
inner_scope_uses_arguments_ = true;
}
- if (inner->scope_uses_super_property_ ||
- inner->inner_scope_uses_super_property_) {
- inner_scope_uses_super_property_ = true;
- }
if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) {
inner_scope_uses_this_ = true;
}
Index: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index
ba842587708dfaaa8053883460b2e2e41f8bdf7f..6b8af3fea2e3a8779f8facd9e296de574d1ada15
100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -961,8 +961,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
SUPER_PROPERTY = 1 << 1,
THIS = 1 << 2,
INNER_ARGUMENTS = 1 << 3,
- INNER_SUPER_PROPERTY = 1 << 4,
- INNER_THIS = 1 << 5
+ INNER_THIS = 1 << 4
};
static const struct {
@@ -978,7 +977,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"return this + arguments[0] + super.x",
ARGUMENTS | SUPER_PROPERTY | THIS},
{"return x => this + x", INNER_THIS},
- {"return x => super.f() + x", INNER_SUPER_PROPERTY},
+ {"return x => super.f() + x", SUPER_PROPERTY},
{"this.foo = 42;", THIS},
{"this.foo();", THIS},
{"if (foo()) { this.f() }", THIS},
@@ -1006,10 +1005,9 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"\"use strict\"; while (true) { let x; this, arguments; }",
INNER_ARGUMENTS | INNER_THIS},
{"\"use strict\"; while (true) { let x; this, super.f(), arguments; }",
- INNER_ARGUMENTS | INNER_SUPER_PROPERTY | INNER_THIS},
+ INNER_ARGUMENTS | SUPER_PROPERTY | INNER_THIS},
{"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS},
- {"\"use strict\"; if (foo()) { let x; super.f() }",
- INNER_SUPER_PROPERTY},
+ {"\"use strict\"; if (foo()) { let x; super.f() }", SUPER_PROPERTY},
{"\"use strict\"; if (1) {"
" let x; return { m() { return this + super.m() + arguments } }"
"}",
@@ -1030,7 +1028,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
for (unsigned i = 0; i < arraysize(source_data); ++i) {
// Super property is only allowed in constructor and method.
if (((source_data[i].expected & SUPER_PROPERTY) ||
- (source_data[i].expected & INNER_SUPER_PROPERTY) ||
(source_data[i].expected == NONE)) && j != 2) {
continue;
}
@@ -1074,8 +1071,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
CHECK_EQ((source_data[i].expected & THIS) != 0, scope->uses_this());
CHECK_EQ((source_data[i].expected & INNER_ARGUMENTS) != 0,
scope->inner_uses_arguments());
- CHECK_EQ((source_data[i].expected & INNER_SUPER_PROPERTY) != 0,
- scope->inner_uses_super_property());
CHECK_EQ((source_data[i].expected & INNER_THIS) != 0,
scope->inner_uses_this());
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.