New issue
Advanced search Search tips

Issue 723132 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: May 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug



Sign in to add a comment

Inconsistent binding of "this" in inline arrow function within a generator.

Project Member Reported by d...@chromium.org, May 17 2017

Issue description

While debugging a LogDog viewer problem ( crbug.com/722541 ), I ran into something weird that seems like it could be a V8 bug. I've created a pretty small repro.

The bug is not present in stable Chromium, but appears to be present in canary:

Google Chrome	60.0.3100.0 (Official Build) dev (64-bit)
Revision	f472642fd6c20b63b0f1a2f62564f2aad56f4be3-refs/heads/master@{#471639}
OS	Linux
JavaScript	V8 6.0.205

I have a class which includes a member function that invokes a wrapper on a generator function. The generator function, in turn, calls an inline arrow function which references "this". I find that if "this" is referenced in the generator function, the arrow function's "this" is properly bound to the class. However, if the generator function does NOT reference "this", the arrow function's "this" is bound to Window.

See attachment for reproduction.

(This looks a lot more reasonable in the source TypeScript.)
 
wut.html
672 bytes View Download

Comment 1 by hpayer@chromium.org, May 17 2017

Owner: adamk@chromium.org
Status: Available (was: Untriaged)
Adam, can you help finding a good owner for this one?

Comment 2 by adamk@chromium.org, May 17 2017

Cc: kkaluri@chromium.org adamk@chromium.org
 Issue 722587  has been merged into this issue.

Comment 3 by adamk@chromium.org, May 17 2017

Labels: OS-All
Status: Started (was: Available)
Looks like a regression from https://chromium.googlesource.com/v8/v8/+/68f0a47b28a96a4966e7b747bfa304b555e726d1, taking a look now.

Comment 4 by adamk@chromium.org, May 17 2017

Cc: marja@chromium.org

Comment 5 by adamk@chromium.org, May 17 2017

+marja as this doesn't repro with --no-lazy-inner-functions.

It seems like lazy-parsing inner arrow functions just happened to work before, since the "this" variable was always used in generator scopes. And it's already broken for "arguments". I think the short-term fix is to stop treating generators in general as "top level", since they can have "interesting" bindings for both "this" and "arguments". For module scopes, it should still be safe to treat them as "top level", since 'this' is always undefined, and there is no 'arguments' binding.

Comment 6 by adamk@chromium.org, May 17 2017

Minimal test case:

```
function outer() {
  function* generator() {
    let arrow = () => { 
      console.log(this, arguments[0]);
    };
    arrow();
  }
  generator.call(this, 'world').next();
}
outer.call('hello');

```

It should print `hello world`, but instead prints `[object global] undefined`.

Comment 7 by adamk@chromium.org, May 17 2017

Proposed fix up for review at https://chromium-review.googlesource.com/c/508055/
Project Member

Comment 8 by bugdroid1@chromium.org, May 18 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/v8/v8.git/+/0439100a5f1264825a99a90cca7c8dd3311944c1

commit 0439100a5f1264825a99a90cca7c8dd3311944c1
Author: Adam Klein <adamk@chromium.org>
Date: Thu May 18 16:24:26 2017

[parser] Stop treating generators as "top level" for preparsing purposes

Generators were previously treated as "top level" for preparsing purposes,
since all their variables are context-allocated. But doing so isn't quite
correct: the allocation of the "arguments" variable for a generator
depends on whether it's referenced, and so an inner arrow function
which references "arguments" won't properly trigger allocation of
"arguments" since the reference will not be noticed in the preparser.

The same problem exists for "this" since commit 68f0a47b28a96a4966e7b747bfa304b555e726d1;
before that commit, all generators implicitly referenced their "this" argument
as part of the desugaring. With that implicit reference gone, "this"
falls into the same problem as arguments.

This patch restricts the special "top level" treatment to modules,
which have only a trivial "this" binding (it's always undefined), and no
arguments binding. Moreover, all code inside modules is strict, meaning
that unresolved references to "this" will also result in undefined.

R=marja@chromium.org

Bug:  chromium:723132 
Change-Id: I814d145fb8f3f1a65abb48e4e35595428d063051
Reviewed-on: https://chromium-review.googlesource.com/508055
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45399}
[modify] https://crrev.com/0439100a5f1264825a99a90cca7c8dd3311944c1/src/ast/scopes.cc
[add] https://crrev.com/0439100a5f1264825a99a90cca7c8dd3311944c1/test/mjsunit/regress/regress-crbug-723132.js

Comment 9 by adamk@chromium.org, May 18 2017

Status: Fixed (was: Started)

Sign in to add a comment