Commit 57e1e72a authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Simplify CheckAndRewriteReferenceExpression

Use the parser's IsValidReferenceExpression as a likely-succeeding precheck.
Slightly optimizes IsEvalOrArguments in the preparser and IsIdentifier for the
parser (we now have FailureExpression everywhere); and replaces
IsObjectLiteral||IsArrayLiteral by IsValidPattern.

Change-Id: I7e9684485c0ce454e640800566eb4b0a24c6bfc8
Reviewed-on: https://chromium-review.googlesource.com/c/1345995
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57682}
parent 1d726111
...@@ -142,10 +142,6 @@ bool Expression::ToBooleanIsFalse() const { ...@@ -142,10 +142,6 @@ bool Expression::ToBooleanIsFalse() const {
} }
bool Expression::IsValidReferenceExpression() const { bool Expression::IsValidReferenceExpression() const {
// We don't want expressions wrapped inside RewritableExpression to be
// considered as valid reference expressions, as they will be rewritten
// to something (most probably involving a do expression).
if (IsRewritableExpression()) return false;
return IsProperty() || return IsProperty() ||
(IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression()); (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression());
} }
......
...@@ -4426,15 +4426,15 @@ ParserBase<Impl>::CheckAndRewriteReferenceExpression(ExpressionT expression, ...@@ -4426,15 +4426,15 @@ ParserBase<Impl>::CheckAndRewriteReferenceExpression(ExpressionT expression,
int beg_pos, int end_pos, int beg_pos, int end_pos,
MessageTemplate message, MessageTemplate message,
ParseErrorType type) { ParseErrorType type) {
if (impl()->IsIdentifier(expression) && is_strict(language_mode()) && if (V8_LIKELY(IsValidReferenceExpression(expression))) return expression;
impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
if (impl()->IsIdentifier(expression)) {
DCHECK(is_strict(language_mode()));
DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
ReportMessageAt(Scanner::Location(beg_pos, end_pos), ReportMessageAt(Scanner::Location(beg_pos, end_pos),
MessageTemplate::kStrictEvalArguments, kSyntaxError); MessageTemplate::kStrictEvalArguments, kSyntaxError);
return impl()->FailureExpression(); return impl()->FailureExpression();
} }
if (expression->IsValidReferenceExpression()) {
return expression;
}
if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) { if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) {
// If it is a call, make it a runtime error for legacy web compatibility. // If it is a call, make it a runtime error for legacy web compatibility.
// Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480 // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
...@@ -5410,8 +5410,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( ...@@ -5410,8 +5410,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
int lhs_end_pos = end_position(); int lhs_end_pos = end_position();
bool is_for_each = CheckInOrOf(&for_info.mode); bool is_for_each = CheckInOrOf(&for_info.mode);
bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || bool is_destructuring = is_for_each && expression->IsValidPattern();
expression->IsObjectLiteral());
if (is_destructuring) { if (is_destructuring) {
ValidateAssignmentPattern(); ValidateAssignmentPattern();
...@@ -5546,7 +5545,7 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations( ...@@ -5546,7 +5545,7 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
ForInfo* for_info, ZonePtrList<const AstRawString>* labels, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels) { ZonePtrList<const AstRawString>* own_labels) {
// Initializer is reference followed by in/of. // Initializer is reference followed by in/of.
if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) { if (!expression->IsValidPattern()) {
expression = CheckAndRewriteReferenceExpression( expression = CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
kSyntaxError); kSyntaxError);
...@@ -5747,7 +5746,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( ...@@ -5747,7 +5746,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
ExpressionT lhs = each_variable = ParseLeftHandSideExpression(); ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
int lhs_end_pos = end_position(); int lhs_end_pos = end_position();
if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) { if (lhs->IsValidPattern()) {
ValidateAssignmentPattern(); ValidateAssignmentPattern();
} else { } else {
ValidateExpression(); ValidateExpression();
......
...@@ -1816,7 +1816,7 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, ...@@ -1816,7 +1816,7 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
return InitializeForOfStatement(for_of, each, subject, body, finalize, return InitializeForOfStatement(for_of, each, subject, body, finalize,
IteratorType::kNormal, each->position()); IteratorType::kNormal, each->position());
} else { } else {
if (each->IsArrayLiteral() || each->IsObjectLiteral()) { if (each->IsValidPattern()) {
Variable* temp = NewTemporary(ast_value_factory()->empty_string()); Variable* temp = NewTemporary(ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
Expression* assign_each = Expression* assign_each =
...@@ -2053,7 +2053,7 @@ Statement* Parser::InitializeForOfStatement( ...@@ -2053,7 +2053,7 @@ Statement* Parser::InitializeForOfStatement(
{ {
assign_each = assign_each =
factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
if (each->IsArrayLiteral() || each->IsObjectLiteral()) { if (each->IsValidPattern()) {
assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment()); assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
} }
} }
......
...@@ -606,8 +606,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -606,8 +606,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// inside a variable proxy). We exclude the case of 'this', which // inside a variable proxy). We exclude the case of 'this', which
// has been converted to a variable proxy. // has been converted to a variable proxy.
V8_INLINE static bool IsIdentifier(Expression* expression) { V8_INLINE static bool IsIdentifier(Expression* expression) {
// TODO(verwaest): Rely on FailureExpression instead.
if (expression == nullptr) return false;
VariableProxy* operand = expression->AsVariableProxy(); VariableProxy* operand = expression->AsVariableProxy();
return operand != nullptr && !operand->is_this() && return operand != nullptr && !operand->is_this() &&
!operand->is_new_target(); !operand->is_new_target();
......
...@@ -58,7 +58,10 @@ class PreParserIdentifier { ...@@ -58,7 +58,10 @@ class PreParserIdentifier {
bool IsEval() const { return type_ == kEvalIdentifier; } bool IsEval() const { return type_ == kEvalIdentifier; }
bool IsAsync() const { return type_ == kAsyncIdentifier; } bool IsAsync() const { return type_ == kAsyncIdentifier; }
bool IsArguments() const { return type_ == kArgumentsIdentifier; } bool IsArguments() const { return type_ == kArgumentsIdentifier; }
bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } bool IsEvalOrArguments() const {
STATIC_ASSERT(kEvalIdentifier + 1 == kArgumentsIdentifier);
return IsInRange(type_, kEvalIdentifier, kArgumentsIdentifier);
}
bool IsConstructor() const { return type_ == kConstructorIdentifier; } bool IsConstructor() const { return type_ == kConstructorIdentifier; }
bool IsAwait() const { return type_ == kAwaitIdentifier; } bool IsAwait() const { return type_ == kAwaitIdentifier; }
bool IsName() const { return type_ == kNameIdentifier; } bool IsName() const { return type_ == kNameIdentifier; }
......
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