Commit 11efb976 authored by ishell's avatar ishell Committed by Commit bot

[es8] Throw SyntaxError when trying to tail call a direct eval.

BUG=v8:4999, v8:4915
LOG=N

Review-Url: https://codereview.chromium.org/1964603002
Cr-Commit-Position: refs/heads/master@{#36126}
parent 7b372433
......@@ -454,6 +454,7 @@ class CallSite {
"Tail call expression in catch block when finally block is also present") \
T(UnexpectedTailCallInForInOf, "Tail call expression in for-in/of body") \
T(UnexpectedTailCallInTryBlock, "Tail call expression in try block") \
T(UnexpectedTailCallOfEval, "Tail call of a direct eval is not allowed") \
T(UnexpectedTemplateString, "Unexpected template string") \
T(UnexpectedToken, "Unexpected token %") \
T(UnexpectedTokenIdentifier, "Unexpected identifier") \
......
......@@ -2234,6 +2234,12 @@ ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
*ok = false;
return Traits::EmptyExpression();
}
if (Traits::IsDirectEvalCall(expression)) {
Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval);
*ok = false;
return Traits::EmptyExpression();
}
if (!is_strict(language_mode())) {
ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall);
*ok = false;
......
......@@ -371,6 +371,12 @@ class ParserTraits {
return expression->AsVariableProxy()->raw_name();
}
bool IsDirectEvalCall(Expression* expression) {
if (!expression->IsCall()) return false;
expression = expression->AsCall()->expression();
return IsIdentifier(expression) && IsEval(AsIdentifier(expression));
}
static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
return ObjectLiteral::IsBoilerplateProperty(property);
}
......
......@@ -175,6 +175,12 @@ class PreParserExpression {
ExpressionTypeField::encode(kCallExpression));
}
static PreParserExpression CallEval() {
return PreParserExpression(
TypeField::encode(kExpression) |
ExpressionTypeField::encode(kCallEvalExpression));
}
static PreParserExpression SuperCallReference() {
return PreParserExpression(
TypeField::encode(kExpression) |
......@@ -236,7 +242,13 @@ class PreParserExpression {
bool IsCall() const {
return TypeField::decode(code_) == kExpression &&
ExpressionTypeField::decode(code_) == kCallExpression;
(ExpressionTypeField::decode(code_) == kCallExpression ||
ExpressionTypeField::decode(code_) == kCallEvalExpression);
}
bool IsDirectEvalCall() const {
return TypeField::decode(code_) == kExpression &&
ExpressionTypeField::decode(code_) == kCallEvalExpression;
}
bool IsSuperCallReference() const {
......@@ -294,6 +306,7 @@ class PreParserExpression {
kThisPropertyExpression,
kPropertyExpression,
kCallExpression,
kCallEvalExpression,
kSuperCallReference,
kNoTemplateTagExpression,
kAssignment
......@@ -503,6 +516,9 @@ class PreParserFactory {
PreParserExpression NewCall(PreParserExpression expression,
PreParserExpressionList arguments,
int pos) {
if (expression.IsIdentifier() && expression.AsIdentifier().IsEval()) {
return PreParserExpression::CallEval();
}
return PreParserExpression::Call();
}
PreParserExpression NewCallNew(PreParserExpression expression,
......@@ -635,6 +651,14 @@ class PreParserTraits {
return expression.AsIdentifier();
}
static bool IsEvalIdentifier(PreParserExpression expression) {
return IsIdentifier(expression) && IsEval(AsIdentifier(expression));
}
static bool IsDirectEvalCall(PreParserExpression expression) {
return expression.IsDirectEvalCall();
}
static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
return identifier.IsFutureStrictReserved();
}
......
// 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: --harmony-explicit-tailcalls
function g() {
return continue eval ("f()") ;
}
*%(basename)s:8: SyntaxError: Tail call of a direct eval is not allowed
return continue eval ("f()") ;
^^^^^^^^^^^^^
SyntaxError: Tail call of a direct eval is not allowed
......@@ -270,6 +270,25 @@ var SyntaxErrorTests = [
},
],
},
{ msg: "Tail call of a direct eval is not allowed",
tests: [
{ src: `()=>{ return continue eval(" foo () " ) ; }`,
err: ` ^^^^^^^^^^^^^^^^^`,
},
{ src: `()=>{ return a || continue eval("", 1, 2) ; }`,
err: ` ^^^^^^^^^^^^^^`,
},
{ src: `()=>{ return a, continue eval ( ) ; }`,
err: ` ^^^^^^^^^`,
},
{ src: `()=> a, continue eval ( ) ; `,
err: ` ^^^^^^^^^`,
},
{ src: `()=> a || continue eval (' ' ) ; `,
err: ` ^^^^^^^^^^^^`,
},
],
},
{ msg: "Undefined label 'foo'",
tests: [
{ src: `()=>{ continue foo () ; }`,
......@@ -285,6 +304,7 @@ var NoErrorTests = [
`()=>{ return continue a.b.c.foo () ; }`,
`()=>{ return continue a().b.c().d.foo () ; }`,
`()=>{ return continue foo (1)(2)(3, 4) ; }`,
`()=>{ return continue (0, eval)(); }`,
`()=>{ return ( continue b() ) ; }`,
"()=>{ return continue bar`ab cd ef` ; }",
"()=>{ return continue bar`ab ${cd} ef` ; }",
......
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