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 {
}
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() ||
(IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression());
}
......
......@@ -4426,15 +4426,15 @@ ParserBase<Impl>::CheckAndRewriteReferenceExpression(ExpressionT expression,
int beg_pos, int end_pos,
MessageTemplate message,
ParseErrorType type) {
if (impl()->IsIdentifier(expression) && is_strict(language_mode()) &&
impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
if (V8_LIKELY(IsValidReferenceExpression(expression))) return expression;
if (impl()->IsIdentifier(expression)) {
DCHECK(is_strict(language_mode()));
DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
ReportMessageAt(Scanner::Location(beg_pos, end_pos),
MessageTemplate::kStrictEvalArguments, kSyntaxError);
return impl()->FailureExpression();
}
if (expression->IsValidReferenceExpression()) {
return expression;
}
if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) {
// 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
......@@ -5410,8 +5410,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
int lhs_end_pos = end_position();
bool is_for_each = CheckInOrOf(&for_info.mode);
bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
expression->IsObjectLiteral());
bool is_destructuring = is_for_each && expression->IsValidPattern();
if (is_destructuring) {
ValidateAssignmentPattern();
......@@ -5546,7 +5545,7 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels) {
// Initializer is reference followed by in/of.
if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) {
if (!expression->IsValidPattern()) {
expression = CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
kSyntaxError);
......@@ -5747,7 +5746,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
int lhs_end_pos = end_position();
if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
if (lhs->IsValidPattern()) {
ValidateAssignmentPattern();
} else {
ValidateExpression();
......
......@@ -1816,7 +1816,7 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
return InitializeForOfStatement(for_of, each, subject, body, finalize,
IteratorType::kNormal, each->position());
} else {
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
if (each->IsValidPattern()) {
Variable* temp = NewTemporary(ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
Expression* assign_each =
......@@ -2053,7 +2053,7 @@ Statement* Parser::InitializeForOfStatement(
{
assign_each =
factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
if (each->IsValidPattern()) {
assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
}
}
......
......@@ -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
// has been converted to a variable proxy.
V8_INLINE static bool IsIdentifier(Expression* expression) {
// TODO(verwaest): Rely on FailureExpression instead.
if (expression == nullptr) return false;
VariableProxy* operand = expression->AsVariableProxy();
return operand != nullptr && !operand->is_this() &&
!operand->is_new_target();
......
......@@ -58,7 +58,10 @@ class PreParserIdentifier {
bool IsEval() const { return type_ == kEvalIdentifier; }
bool IsAsync() const { return type_ == kAsyncIdentifier; }
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 IsAwait() const { return type_ == kAwaitIdentifier; }
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