Skip to content
Snippets Groups Projects
Commit 78482489 authored by Mike Pennisi's avatar Mike Pennisi Committed by Leonardo Balter
Browse files

Extend coverage for eval code

Closes #572

Introduce tests for new semantics for ES2015 features such as
lexically-scoped bindings. Also add tests for semantics defined in prior
editions of the specification but not yet covered in this test suite.
parent 28725371
Branches
No related tags found
No related merge requests found
Showing
with 550 additions and 0 deletions
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates a new declarative environment for lexically-scoped
declarations (class)
info: |
[...]
9. If direct is true, then
a. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
[...]
features: [class]
---*/
class outside {}
eval('class outside {}');
eval('"use strict"; class outside {}');
eval('class xNonStrict {}');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
eval('"use strict"; class xStrict {}');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates a new declarative environment for lexically-scoped
declarations (const)
info: |
[...]
9. If direct is true, then
a. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
[...]
features: [const]
---*/
const outside = null;
eval('const outside = null;');
eval('"use strict"; const outside = null;');
eval('const xNonStrict = null;');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
eval('"use strict"; const xStrict = null;');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates a new declarative environment for lexically-scoped
declarations (let)
info: |
[...]
9. If direct is true, then
a. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
[...]
features: [let]
---*/
let outside = 23;
eval('let outside;');
eval('"use strict"; let outside;');
eval('let xNonStrict = 3;');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
eval('"use strict"; let xStrict = 3;');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code sets the new declarative environment's outer environment
to that of the current context.
info: |
[...]
9. If direct is true, then
a. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
[...]
features: [let]
---*/
var actualStrict;
var actualNonStrict;
let x = 'outside';
{
let x = 'inside';
actualNonStrict = eval('x;');
actualStrict = eval('"use strict"; x;');
}
assert.sameValue(actualNonStrict, 'inside', 'non strict mode');
assert.sameValue(actualStrict, 'inside', 'strict mode');
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates `class` bindings prior to evaluation, but does not
initialize them.
info: |
[...]
14. For each element d in lexDeclarations do
a. NOTE Lexically declared names are only instantiated here but not
initialized.
b. For each element dn of the BoundNames of d do
i. If IsConstantDeclaration of d is true, then
1. Perform ? lexEnvRec.CreateImmutableBinding(dn, true).
ii. Else,
2. Perform ? lexEnvRec.CreateMutableBinding(dn, false).
[...]
features: [class]
---*/
assert.throws(ReferenceError, function() {
eval('typeof C; class C {}');
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates `const` bindings prior to evaluation but does not
initialize them.
info: |
[...]
14. For each element d in lexDeclarations do
a. NOTE Lexically declared names are only instantiated here but not
initialized.
b. For each element dn of the BoundNames of d do
i. If IsConstantDeclaration of d is true, then
1. Perform ? lexEnvRec.CreateImmutableBinding(dn, true).
ii. Else,
2. Perform ? lexEnvRec.CreateMutableBinding(dn, false).
[...]
features: [const]
---*/
assert.throws(ReferenceError, function() {
eval('typeof x; const x = null;');
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-performeval
description: >
Direct eval code creates `let` bindings prior to evaluation but does not
initialize them.
info: |
[...]
14. For each element d in lexDeclarations do
a. NOTE Lexically declared names are only instantiated here but not
initialized.
b. For each element dn of the BoundNames of d do
i. If IsConstantDeclaration of d is true, then
1. Perform ? lexEnvRec.CreateImmutableBinding(dn, true).
ii. Else,
2. Perform ? lexEnvRec.CreateMutableBinding(dn, false).
[...]
features: [let]
---*/
assert.throws(ReferenceError, function() {
eval('typeof x; let x;');
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Evaluated code honors a Use Strict Directive in the Directive Prologue
esid: sec-strict-mode-code
info: |
Eval code is strict mode code if it begins with a Directive Prologue that
contains a Use Strict Directive or if the call to eval is a direct eval
that is contained in strict mode code.
---*/
assert.throws(ReferenceError, function() {
eval('"use strict"; unresolvable = null;');
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Direct eval code has the same `this` binding as the calling context (strict
function scope)
esid: sec-performeval
flags: [noStrict]
---*/
var thisValue;
(function() {
thisValue = eval('"use strict"; this;');
}());
assert.sameValue(thisValue, this);
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Initialization of new global property
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalFunctionBinding(fn, fo, true).
[...]
8.1.1.4.18 CreateGlobalFunctionBinding
[...]
5. If existingProp is undefined or existingProp.[[Configurable]] is true,
then
a. Let desc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true,
[[Enumerable]]: true, [[Configurable]]: D}.
6. Else,
[...]
7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
[...]
flags: [noStrict]
includes: [propertyHelper.js]
---*/
var initial;
eval('initial = f; function f() { return 234; }');
verifyEnumerable(this, 'f');
verifyWritable(this, 'f');
verifyConfigurable(this, 'f');
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 234);
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Modification of previously-existing configurable global property
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalFunctionBinding(fn, fo, true).
[...]
8.1.1.4.18 CreateGlobalFunctionBinding
[...]
5. If existingProp is undefined or existingProp.[[Configurable]] is true,
then
a. Let desc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true,
[[Enumerable]]: true, [[Configurable]]: D}.
6. Else,
[...]
7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
[...]
flags: [noStrict]
includes: [propertyHelper.js]
---*/
var initial = null;
Object.defineProperty(this, 'f', {
enumerable: false,
writable: false,
configurable: true
});
eval('initial = f; function f() { return 345; }');
verifyEnumerable(this, 'f');
verifyWritable(this, 'f');
verifyConfigurable(this, 'f');
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 345);
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: >
Modification of previously-existing non-configurable global property
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalFunctionBinding(fn, fo, true).
[...]
8.1.1.4.18 CreateGlobalFunctionBinding
[...]
5. If existingProp is undefined or existingProp.[[Configurable]] is true,
then
[...]
6. Else,
b. Let desc be the PropertyDescriptor{[[Value]]: V }.
7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
[...]
flags: [noStrict]
includes: [propertyHelper.js]
---*/
var initial;
Object.defineProperty(this, 'f', {
enumerable: true,
writable: true,
configurable: false
});
eval('initial = f; function f() { return 2222; }');
verifyEnumerable(this, 'f');
verifyWritable(this, 'f');
verifyNotConfigurable(this, 'f');
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 2222);
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Newly-created local binding may be deleted
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
[...]
d. Else,
i. Let bindingExists be varEnvRec.HasBinding(fn).
ii. If bindingExists is false, then
1. Let status be ! varEnvRec.CreateMutableBinding(fn, true).
2. Assert: status is not an abrupt completion because of
validation preceding step 12.
3. Perform ! varEnvRec.InitializeBinding(fn, fo).
[...]
flags: [noStrict]
---*/
var initial, postDeletion;
(function() {
eval('initial = f; delete f; postDeletion = function() { f; }; function f() { return 33; }');
}());
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 33);
assert.throws(ReferenceError, postDeletion, 'binding may be deleted');
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Initialization of new local binding
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
[...]
d. Else,
i. Let bindingExists be varEnvRec.HasBinding(fn).
ii. If bindingExists is false, then
1. Let status be ! varEnvRec.CreateMutableBinding(fn, true).
2. Assert: status is not an abrupt completion because of
validation preceding step 12.
3. Perform ! varEnvRec.InitializeBinding(fn, fo).
[...]
flags: [noStrict]
---*/
var initial, postAssignment;
(function() {
eval('initial = f; f = 5; postAssignment = f; function f() { return 33; }');
}());
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 33);
assert.sameValue(postAssignment, 5, 'binding is mutable');
assert.throws(ReferenceError, function() {
f;
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Re-declaration of an existing local variable binding
info: |
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
c. If varEnvRec is a global Environment Record, then
[...]
d. Else,
i. Let bindingExists be varEnvRec.HasBinding(fn).
ii. If bindingExists is false, then
[...]
iii. Else,
1. Perform ! varEnvRec.SetMutableBinding(fn, fo, false).
[...]
flags: [noStrict]
---*/
var initial;
(function() {
var f = 88;
eval('initial = f; function f() { return 33; }');
}());
assert.sameValue(typeof initial, 'function');
assert.sameValue(initial(), 33);
assert.throws(ReferenceError, function() {
f;
});
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Precedence of final declaration when bindings are duplicated
info: |
[...]
8. For each d in varDeclarations, in reverse list order do
a. If d is neither a VariableDeclaration or a ForBinding, then
i. Assert: d is either a FunctionDeclaration or a
GeneratorDeclaration.
[...]
iv. If fn is not an element of declaredFunctionNames, then
[...]
3. Insert d as the first element of functionsToInitialize.
[...]
15. For each production f in functionsToInitialize, do
a. Let fn be the sole element of the BoundNames of f.
b. Let fo be the result of performing InstantiateFunctionObject for f
with argument lexEnv.
[...]
flags: [noStrict]
---*/
var initial;
eval('initial = f; function f() { return "first"; } function f() { return "second"; }');
assert.sameValue(initial(), 'second', 'initial value');
assert.sameValue(f(), 'second', 'value following declaration evaluation');
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: No variable collision with global lexical binding
info: |
[...]
5. If strict is false, then
[...]
flags: [onlyStrict]
features: [let]
---*/
let x;
eval('var x;');
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: Variable collision with global lexical binding
info: |
[...]
5. If strict is false, then
a. If varEnvRec is a global Environment Record, then
i. For each name in varNames, do
1. If varEnvRec.HasLexicalDeclaration(name) is true, throw a
SyntaxError exception.
2. NOTE: eval will not create a global var declaration that would
be shadowed by a global lexical declaration.
[...]
negative: SyntaxError
flags: [noStrict]
features: [let]
---*/
let x;
// Although the `try` statement is a more precise mechanism for detecting
// runtime errors, the behavior under test is only observable for a direct eval
// call when the call is made from the global scope. This forces the use of
// the more coarse-grained `negative` frontmatter to assert the expected error.
eval('var x;');
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-evaldeclarationinstantiation
description: No variable collision with global lexical binding
info: |
[...]
5. If strict is false, then
[...]
features: [let]
---*/
let x;
eval('"use strict"; var x;');
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment