Commit 68235eb9 authored by Caitlin Potter's avatar Caitlin Potter Committed by Commit Bot

[parser] don't treat new.target as a valid DestructuringAssignmentTarget

BUG=v8:6291, v8:811
R=marja@chromium.org, vogelheim@chromium.org

Change-Id: Icf18b1cba8562aab87d233d383eb1d73a8e6aa9d
Reviewed-on: https://chromium-review.googlesource.com/485059
Commit-Queue: Caitlin Potter <caitp@igalia.com>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44818}
parent a91333df
......@@ -3547,6 +3547,10 @@ ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
int pos = position();
ExpectMetaProperty(Token::TARGET, "new.target", pos, CHECK_OK);
classifier()->RecordAssignmentPatternError(
Scanner::Location(pos, scanner()->location().end_pos),
MessageTemplate::kInvalidDestructuringTarget);
if (!GetReceiverScope()->is_function_scope()) {
impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedNewTarget);
......
......@@ -723,7 +723,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
V8_INLINE static bool IsIdentifier(Expression* expression) {
DCHECK_NOT_NULL(expression);
VariableProxy* operand = expression->AsVariableProxy();
return operand != nullptr && !operand->is_this();
return operand != nullptr && !operand->is_this() &&
!operand->is_new_target();
}
V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
......
......@@ -178,6 +178,11 @@ class PreParserExpression {
variables);
}
static PreParserExpression NewTargetExpression() {
return PreParserExpression(TypeField::encode(kExpression) |
ExpressionTypeField::encode(kNewTarget));
}
static PreParserExpression ObjectLiteral(
ZoneList<VariableProxy*>* variables) {
return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
......@@ -358,7 +363,8 @@ class PreParserExpression {
kCallEvalExpression,
kSuperCallReference,
kNoTemplateTagExpression,
kAssignment
kAssignment,
kNewTarget
};
explicit PreParserExpression(uint32_t expression_code,
......@@ -387,7 +393,7 @@ class PreParserExpression {
// The rest of the bits are interpreted depending on the value
// of the Type field, so they can share the storage.
typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
typedef BitField<ExpressionType, TypeField::kNext, 4> ExpressionTypeField;
typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseAsmField;
typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
......@@ -1519,7 +1525,7 @@ class PreParser : public ParserBase<PreParser> {
}
V8_INLINE PreParserExpression NewTargetExpression(int pos) {
return PreParserExpression::Default();
return PreParserExpression::NewTargetExpression();
}
V8_INLINE PreParserExpression FunctionSentExpression(int pos) {
......
......@@ -478,3 +478,58 @@ assertEquals(oz, [1, 2, 3, 4, 5]);
{ firstLetter: "B", rest: ["p", "u", "p", "p", "y"] },
], log);
})();
(function testNewTarget() {
assertThrows("(function() { [...new.target] = []; })", SyntaxError);
assertThrows("(function() { [a] = [...new.target] = []; })", SyntaxError);
assertThrows("(function() { [new.target] = []; })", SyntaxError);
assertThrows("(function() { [a] = [new.target] = []; })", SyntaxError);
assertThrows("(function() { ({ a: new.target] = {a: 0}); })", SyntaxError);
assertThrows("(function() { ({ a } = { a: new.target } = {}); })",
SyntaxError);
function ReturnNewTarget1() {
var result;
[result = new.target] = [];
return result;
}
function ReturnNewTarget2() {
var result;
[result] = [new.target];
return result;
}
function ReturnNewTarget3() {
var result;
({ result = new.target } = {});
return result;
}
function ReturnNewTarget4() {
var result;
({ result } = { result: new.target });
return result;
}
function FakeNewTarget() {}
assertEquals(undefined, ReturnNewTarget1());
assertEquals(ReturnNewTarget1, new ReturnNewTarget1());
assertEquals(FakeNewTarget,
Reflect.construct(ReturnNewTarget1, [], FakeNewTarget));
assertEquals(undefined, ReturnNewTarget2());
assertEquals(ReturnNewTarget2, new ReturnNewTarget2());
assertEquals(FakeNewTarget,
Reflect.construct(ReturnNewTarget2, [], FakeNewTarget));
assertEquals(undefined, ReturnNewTarget3());
assertEquals(ReturnNewTarget3, new ReturnNewTarget3());
assertEquals(FakeNewTarget,
Reflect.construct(ReturnNewTarget3, [], FakeNewTarget));
assertEquals(undefined, ReturnNewTarget4());
assertEquals(ReturnNewTarget4, new ReturnNewTarget4());
assertEquals(FakeNewTarget,
Reflect.construct(ReturnNewTarget4, [], FakeNewTarget));
})();
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