Commit c8a342a5 authored by adamk's avatar adamk Committed by Commit bot

Fix 'eval' in class extends clauses to be always-strict

Compiler backends get their language mode from the current
function, but should instead be deriving it from the current scope.
This allows proper handling of the always-strictness of class declarations
and expressions, and in particular the treatment of 'eval' calls in an
extends clause as a strict eval.

Also fix the parser's RecordEvalCall logic to only reach out to the
DeclarationScope in sloppy mode, which fixes the strange case of a
sloppy function thinking it contains a sloppy eval when in fact
it contains only a strict eval.

BUG=v8:4970
LOG=n

Review-Url: https://codereview.chromium.org/1931003003
Cr-Commit-Position: refs/heads/master@{#36001}
parent d2efbf25
......@@ -3080,7 +3080,7 @@ void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
LanguageMode AstGraphBuilder::language_mode() const {
return info()->language_mode();
return current_scope()->language_mode();
}
......
......@@ -711,7 +711,7 @@ class FullCodeGenerator: public AstVisitor {
Handle<Script> script() { return info_->script(); }
bool is_eval() { return info_->is_eval(); }
bool is_native() { return info_->is_native(); }
LanguageMode language_mode() { return literal()->language_mode(); }
LanguageMode language_mode() { return scope()->language_mode(); }
bool has_simple_parameters() { return info_->has_simple_parameters(); }
FunctionLiteral* literal() const { return info_->literal(); }
Scope* scope() { return scope_; }
......
......@@ -3276,7 +3276,7 @@ void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
LanguageMode BytecodeGenerator::language_mode() const {
return info()->language_mode();
return execution_context()->scope()->language_mode();
}
......
......@@ -904,8 +904,12 @@ class ParserBase : public Traits {
void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
if (Traits::IsIdentifier(expression) &&
Traits::IsEval(Traits::AsIdentifier(expression))) {
scope->DeclarationScope()->RecordEvalCall();
scope->RecordEvalCall();
if (is_sloppy(scope->language_mode())) {
// For sloppy scopes we also have to record the call at function level,
// in case it includes declarations that will be hoisted.
scope->DeclarationScope()->RecordEvalCall();
}
}
}
......
// Copyright 2016 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.
//
// Flags: --allow-natives-syntax
function g() {
var f;
class C extends eval("f = () => delete C; Array") {}
f();
}
assertThrows(g, SyntaxError);
%OptimizeFunctionOnNextCall(g);
assertThrows(g, SyntaxError);
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