Commit 9acfd4fe authored by arv's avatar arv Committed by Commit bot

super is only allowed in methods, accessors and constructor

super() is only allowed in a class constructor.
super.p is allowed in methods, accessors and constructors.

The parser now checks the FunctionState to see what kind of function
we are currently inside.

BUG=v8:3330
LOG=N
R=dslomov@chromium.org, marja@chromium.org

Review URL: https://codereview.chromium.org/915563003

Cr-Commit-Position: refs/heads/master@{#26557}
parent 5cd84502
...@@ -217,6 +217,7 @@ class ParserBase : public Traits { ...@@ -217,6 +217,7 @@ class ParserBase : public Traits {
bool is_generator() const { return IsGeneratorFunction(kind_); } bool is_generator() const { return IsGeneratorFunction(kind_); }
FunctionKind kind() const { return kind_; } FunctionKind kind() const { return kind_; }
FunctionState* outer() const { return outer_function_state_; }
void set_generator_object_variable( void set_generator_object_variable(
typename Traits::Type::GeneratorVariable* variable) { typename Traits::Type::GeneratorVariable* variable) {
...@@ -249,7 +250,6 @@ class ParserBase : public Traits { ...@@ -249,7 +250,6 @@ class ParserBase : public Traits {
// for generator functions to have this variable set. // for generator functions to have this variable set.
Variable* generator_object_variable_; Variable* generator_object_variable_;
FunctionState** function_state_stack_; FunctionState** function_state_stack_;
FunctionState* outer_function_state_; FunctionState* outer_function_state_;
Scope** scope_stack_; Scope** scope_stack_;
...@@ -569,6 +569,7 @@ class ParserBase : public Traits { ...@@ -569,6 +569,7 @@ class ParserBase : public Traits {
bool* ok); bool* ok);
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
void AddTemplateExpression(ExpressionT); void AddTemplateExpression(ExpressionT);
ExpressionT ParseSuperExpression(bool is_new, bool* ok);
// Checks if the expression is a valid reference expression (e.g., on the // Checks if the expression is a valid reference expression (e.g., on the
// left-hand side of assignments). Although ruled out by ECMA as early errors, // left-hand side of assignments). Although ruled out by ECMA as early errors,
...@@ -2666,8 +2667,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { ...@@ -2666,8 +2667,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
Consume(Token::NEW); Consume(Token::NEW);
int new_pos = position(); int new_pos = position();
ExpressionT result = this->EmptyExpression(); ExpressionT result = this->EmptyExpression();
if (Check(Token::SUPER)) { if (peek() == Token::SUPER) {
result = this->SuperReference(scope_, factory()); const bool is_new = true;
result = ParseSuperExpression(is_new, CHECK_OK);
} else { } else {
result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
} }
...@@ -2724,21 +2726,8 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) { ...@@ -2724,21 +2726,8 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
CHECK_OK); CHECK_OK);
} else if (peek() == Token::SUPER) { } else if (peek() == Token::SUPER) {
int beg_pos = position(); const bool is_new = false;
Consume(Token::SUPER); result = ParseSuperExpression(is_new, CHECK_OK);
Token::Value next = peek();
if (next == Token::PERIOD || next == Token::LBRACK) {
scope_->RecordSuperPropertyUsage();
result = this->SuperReference(scope_, factory());
} else if (next == Token::LPAREN) {
scope_->RecordSuperConstructorCallUsage();
result = this->SuperReference(scope_, factory());
} else {
ReportMessageAt(Scanner::Location(beg_pos, position()),
"unexpected_super");
*ok = false;
return this->EmptyExpression();
}
} else { } else {
result = ParsePrimaryExpression(CHECK_OK); result = ParsePrimaryExpression(CHECK_OK);
} }
...@@ -2748,6 +2737,39 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) { ...@@ -2748,6 +2737,39 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
} }
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
int beg_pos = position();
Expect(Token::SUPER, CHECK_OK);
FunctionState* function_state = function_state_;
while (IsArrowFunction(function_state->kind())) {
function_state = function_state->outer();
}
// TODO(arv): Handle eval scopes similarly.
FunctionKind kind = function_state->kind();
if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
i::IsConstructor(kind)) {
if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
scope_->RecordSuperPropertyUsage();
return this->SuperReference(scope_, factory());
}
// new super() is never allowed.
// super() is only allowed in constructor
if (!is_new && peek() == Token::LPAREN && i::IsConstructor(kind)) {
scope_->RecordSuperConstructorCallUsage();
return this->SuperReference(scope_, factory());
}
}
ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super");
*ok = false;
return this->EmptyExpression();
}
template <class Traits> template <class Traits>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
......
This diff is collapsed.
...@@ -874,10 +874,4 @@ function assertAccessorDescriptor(object, name) { ...@@ -874,10 +874,4 @@ function assertAccessorDescriptor(object, name) {
} }
}; };
new C3(); new C3();
class C4 extends Object {
constructor() {
super(new super());
}
}; new C4();
}()); }());
...@@ -22,15 +22,6 @@ ...@@ -22,15 +22,6 @@
set accessor(v) { set accessor(v) {
super.accessor = v; super.accessor = v;
}, },
property: function() {
super.property();
},
propertyWithParen: (function() {
super.property();
}),
propertyWithParens: ((function() {
super.property();
})),
methodNoSuper() {}, methodNoSuper() {},
get getterNoSuper() {}, get getterNoSuper() {},
...@@ -50,9 +41,6 @@ ...@@ -50,9 +41,6 @@
desc = Object.getOwnPropertyDescriptor(object, 'accessor'); desc = Object.getOwnPropertyDescriptor(object, 'accessor');
assertEquals(object, desc.get[%HomeObjectSymbol()]); assertEquals(object, desc.get[%HomeObjectSymbol()]);
assertEquals(object, desc.set[%HomeObjectSymbol()]); assertEquals(object, desc.set[%HomeObjectSymbol()]);
assertEquals(object, object.property[%HomeObjectSymbol()]);
assertEquals(object, object.propertyWithParen[%HomeObjectSymbol()]);
assertEquals(object, object.propertyWithParens[%HomeObjectSymbol()]);
assertEquals(undefined, object.methodNoSuper[%HomeObjectSymbol()]); assertEquals(undefined, object.methodNoSuper[%HomeObjectSymbol()]);
desc = Object.getOwnPropertyDescriptor(object, 'getterNoSuper'); desc = Object.getOwnPropertyDescriptor(object, 'getterNoSuper');
...@@ -118,21 +106,6 @@ ...@@ -118,21 +106,6 @@
})(); })();
(function TestMethodAsProperty() {
var object = {
__proto__: {
method: function(x) {
return 'proto' + x;
}
},
method: function(x) {
return super.method(x);
}
};
assertEquals('proto42', object.method(42));
})();
(function TestOptimized() { (function TestOptimized() {
// Object literals without any accessors get optimized. // Object literals without any accessors get optimized.
var object = { var object = {
...@@ -154,15 +127,7 @@ ...@@ -154,15 +127,7 @@
*g() { *g() {
yield super.m(); yield super.m();
}, },
g2: function*() {
yield super.m() + 1;
},
g3: (function*() {
yield super.m() + 2;
})
}; };
assertEquals(42, o.g().next().value); assertEquals(42, o.g().next().value);
assertEquals(43, o.g2().next().value);
assertEquals(44, o.g3().next().value);
})(); })();
This diff is collapsed.
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
# TODO(arv): TurboFan does not yet add [[HomeObject]] as needed. # TODO(arv): TurboFan does not yet add [[HomeObject]] as needed.
'harmony/object-literals-super': [PASS, NO_VARIANTS], 'harmony/object-literals-super': [PASS, NO_VARIANTS],
'harmony/super': [PASS, NO_VARIANTS],
############################################################################## ##############################################################################
# Too slow in debug mode with --stress-opt mode. # Too slow in debug mode with --stress-opt mode.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment