Commit 0439100a authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

[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 68f0a47b;
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/508055Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45399}
parent b14a9814
......@@ -1371,9 +1371,10 @@ bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
if (s->is_catch_scope()) continue;
// With scopes do not introduce variables that need allocation.
if (s->is_with_scope()) continue;
// If everything is guaranteed to be context allocated we can ignore the
// scope.
if (s->has_forced_context_allocation()) continue;
// Module scopes context-allocate all variables, and have no
// {this} or {arguments} variables whose existence depends on
// references to them.
if (s->is_module_scope()) continue;
// Only block scopes and function scopes should disallow preparsing.
DCHECK(s->is_block_scope() || s->is_function_scope());
return false;
......
// Copyright 2017 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 outer() {
function* generator() {
let arrow = () => {
assertSame(expectedReceiver, this);
assertEquals(42, arguments[0]);
};
arrow();
}
generator.call(this, 42).next();
}
let expectedReceiver = {};
outer.call(expectedReceiver);
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