Commit 8a9e3f64 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[ast] Store correct source position on ThisExpression

Previously, all ThisExpression's had kNoSourcePositions leading to
incorrect error messages like this:

  ➜ d8 -e "function t() { for (const x of this) {} } t();"
  unnamed:1: TypeError: undefined is not a function
  function t() { for (const x of this) {} } t();
            ^
  TypeError: undefined is not a function
      at t (unnamed:1:11)
      at unnamed:1:43


This patch allows creation of a ThisExpression with a source position,
leading to a better error message:

  ➜ d8  -e "function t() { for (const x of this) {} } t();"
  unnamed:1: TypeError: this is not iterable
  function t() { for (const x of this) {} } t();
                                 ^
  TypeError: this is not iterable
      at t (unnamed:1:32)
      at unnamed:1:43


This patch does not remove the existing cached version of
ThisExpression and instead creates a new one when required.

Bug: v8:6513
Change-Id: Idee4fe8946a9b821d06ff4a5e7eaefe54874ec59
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2345226Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69300}
parent 4c3cc31c
......@@ -1411,7 +1411,7 @@ class ThisExpression final : public Expression {
private:
friend class AstNodeFactory;
friend Zone;
ThisExpression() : Expression(kNoSourcePosition, kThisExpression) {}
explicit ThisExpression(int pos) : Expression(pos, kThisExpression) {}
};
class VariableProxy final : public Expression {
......@@ -2737,7 +2737,7 @@ class AstNodeFactory final {
: zone_(zone),
ast_value_factory_(ast_value_factory),
empty_statement_(zone->New<class EmptyStatement>()),
this_expression_(zone->New<class ThisExpression>()),
this_expression_(zone->New<class ThisExpression>(kNoSourcePosition)),
failure_expression_(zone->New<class FailureExpression>()) {}
AstNodeFactory* ast_node_factory() { return this; }
......@@ -2904,6 +2904,11 @@ class AstNodeFactory final {
return this_expression_;
}
class ThisExpression* NewThisExpression(int pos) {
DCHECK_NE(pos, kNoSourcePosition);
return zone_->New<class ThisExpression>(pos);
}
class FailureExpression* FailureExpression() {
return failure_expression_;
}
......
......@@ -1833,7 +1833,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
case Token::THIS: {
Consume(Token::THIS);
return impl()->ThisExpression();
return impl()->NewThisExpression(beg_pos);
}
case Token::ASSIGN_DIV:
......
......@@ -786,6 +786,11 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return factory()->ThisExpression();
}
class ThisExpression* NewThisExpression(int pos) {
UseThis();
return factory()->NewThisExpression(pos);
}
Expression* NewSuperPropertyReference(int pos);
Expression* NewSuperCallReference(int pos);
Expression* NewTargetExpression(int pos);
......
......@@ -1533,6 +1533,11 @@ class PreParser : public ParserBase<PreParser> {
return PreParserExpression::This();
}
V8_INLINE PreParserExpression NewThisExpression(int pos) {
UseThis();
return PreParserExpression::This();
}
V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_function_string(), pos,
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function t() {
for (const _ of this) {}
}
t();
# Copyright 2020 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
*%(basename)s:6: TypeError: this is not iterable
for (const _ of this) {}
^
TypeError: this is not iterable
at t (*%(basename)s:6:19)
at *%(basename)s:9:1
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