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.
This commit is contained in:
Mike Pennisi 2016-04-05 17:45:27 -04:00 committed by Leonardo Balter
parent 2872537136
commit 784824895d
50 changed files with 1409 additions and 0 deletions

View File

@ -0,0 +1,33 @@
// 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;
});

View File

@ -0,0 +1,33 @@
// 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;
});

View File

@ -0,0 +1,33 @@
// 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;
});

View File

@ -0,0 +1,27 @@
// 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');

View File

@ -0,0 +1,24 @@
// 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 {}');
});

View File

@ -0,0 +1,24 @@
// 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;');
});

View File

@ -0,0 +1,24 @@
// 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;');
});

View File

@ -0,0 +1,15 @@
// 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;');
});

View File

@ -0,0 +1,17 @@
// 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);

View File

@ -0,0 +1,39 @@
// 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);

View File

@ -0,0 +1,45 @@
// 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);

View File

@ -0,0 +1,45 @@
// 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);

View File

@ -0,0 +1,32 @@
// 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');

View File

@ -0,0 +1,35 @@
// 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;
});

View File

@ -0,0 +1,35 @@
// 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;
});

View File

@ -0,0 +1,30 @@
// 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');

View File

@ -0,0 +1,16 @@
// 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;');

View File

@ -0,0 +1,28 @@
// 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;');

View File

@ -0,0 +1,15 @@
// 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;');

View File

@ -0,0 +1,34 @@
// 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 lexical binding in lower scope
info: |
[...]
5. If strict is false, then
[...]
d. Repeat while thisLex is not the same as varEnv,
i. Let thisEnvRec be thisLex's EnvironmentRecord.
ii. If thisEnvRec is not an object Environment Record, then
1. NOTE: The environment of with statements cannot contain any
lexical declaration so it doesn't need to be checked for
var/let hoisting conflicts.
2. For each name in varNames, do
a. If thisEnvRec.HasBinding(name) is true, then
i. Throw a SyntaxError exception.
b. NOTE: A direct eval will not hoist var declaration over a
like-named lexical declaration.
iii. Let thisLex be thisLex's outer environment reference.
[...]
flags: [noStrict]
features: [let]
---*/
assert.throws(SyntaxError, function() {
{
let x;
{
eval('var x;');
}
}
});

View File

@ -0,0 +1,19 @@
// 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 lexical binding in lower scope
info: |
[...]
5. If strict is false, then
[...]
flags: [onlyStrict]
features: [let]
---*/
{
let x;
{
eval('var x;');
}
}

View File

@ -0,0 +1,18 @@
// 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 lexical binding in lower scope
info: |
[...]
5. If strict is false, then
[...]
features: [let]
---*/
{
let x;
{
eval('"use strict"; var x;');
}
}

View File

@ -0,0 +1,33 @@
// 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: Declaration does not modify existing global property
info: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true).
[...]
8.1.1.4.17 CreateGlobalVarBinding
[...]
5. Let extensible be ? IsExtensible(globalObject).
6. If hasProperty is false and extensible is true, then
[...]
[...]
flags: [noStrict]
includes: [propertyHelper.js]
---*/
var initial;
var x = 23;
eval('initial = x; var x = 45;');
verifyEnumerable(this, 'x');
verifyWritable(this, 'x');
verifyNotConfigurable(this, 'x');
assert.sameValue(initial, 23);

View File

@ -0,0 +1,33 @@
// 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: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true).
[...]
8.1.1.4.17 CreateGlobalVarBinding
[...]
5. Let extensible be ? IsExtensible(globalObject).
6. If hasProperty is false and extensible is true, then
a. Perform ? ObjRec.CreateMutableBinding(N, D).
b. Perform ? ObjRec.InitializeBinding(N, undefined).
[...]
flags: [noStrict]
includes: [propertyHelper.js]
---*/
var initial = null;
eval('initial = x; var x;');
verifyEnumerable(this, 'x');
verifyWritable(this, 'x');
verifyConfigurable(this, 'x');
assert.sameValue(initial, undefined);

View File

@ -0,0 +1,29 @@
// 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 has no effect
info: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
[...]
b. Else,
i. Let bindingExists be varEnvRec.HasBinding(vn).
ii. If bindingExists is false, then
[...]
[...]
flags: [noStrict]
---*/
var initial;
(function() {
var x = 44443;
eval('initial = x; var x;');
}());
assert.sameValue(initial, 44443);
assert.throws(ReferenceError, function() {
x;
});

View File

@ -0,0 +1,30 @@
// 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: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
[...]
b. Else,
i. Let bindingExists be varEnvRec.HasBinding(vn).
ii. If bindingExists is false, then
1. Let status be ! varEnvRec.CreateMutableBinding(vn, true).
2. Assert: status is not an abrupt completion because of
validation preceding step 12.
3. Perform ! varEnvRec.InitializeBinding(vn, undefined).
[...]
flags: [noStrict]
---*/
var initial = null;
var postDeletion;
(function() {
eval('initial = x; delete x; postDeletion = function() { x; }; var x;');
}());
assert.sameValue(initial, undefined);
assert.throws(ReferenceError, postDeletion);

View File

@ -0,0 +1,33 @@
// 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 variable binding
info: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
[...]
b. Else,
i. Let bindingExists be varEnvRec.HasBinding(vn).
ii. If bindingExists is false, then
1. Let status be ! varEnvRec.CreateMutableBinding(vn, true).
2. Assert: status is not an abrupt completion because of
validation preceding step 12.
3. Perform ! varEnvRec.InitializeBinding(vn, undefined).
[...]
flags: [noStrict]
---*/
var initial = null;
var postAssignment;
(function() {
eval('initial = x; x = 4; postAssignment = x; var x;');
}());
assert.sameValue(initial, undefined);
assert.sameValue(postAssignment, 4, 'binding is mutable');
assert.throws(ReferenceError, function() {
x;
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Strictness of direct eval is not dependent on strictness of caller
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.
flags: [onlyStrict]
---*/
var count = 0;
(0,eval)('var static; count += 1;');
assert.sameValue(count, 1);
(0,eval)('with ({}) {} count += 1;');
assert.sameValue(count, 2);
(0,eval)('unresolvable = null; count += 1;');
assert.sameValue(count, 3);

View File

@ -0,0 +1,35 @@
// 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: >
Indirect eval code creates a new declarative environment for
lexically-scoped declarations (class)
info: |
[...]
9. If direct is true, then
[...]
10. Else,
a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
[...]
features: [class]
---*/
class outside {}
(0,eval)('class outside {}');
(0,eval)('"use strict"; class outside {}');
(0,eval)('class xNonStrict {}');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
(0,eval)('"use strict"; class xStrict {}');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});

View File

@ -0,0 +1,35 @@
// 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: >
Indirect eval code creates a new declarative environment for
lexically-scoped declarations (const)
info: |
[...]
9. If direct is true, then
[...]
10. Else,
a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
[...]
features: [const]
---*/
const outside = null;
(0,eval)('const outside = null;');
(0,eval)('"use strict"; const outside = null;');
(0,eval)('const xNonStrict = null;');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
(0,eval)('"use strict"; const xStrict = null;');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});

View File

@ -0,0 +1,35 @@
// 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: >
Indirect eval code creates a new declarative environment for
lexically-scoped declarations (let)
info: |
[...]
9. If direct is true, then
[...]
10. Else,
a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
[...]
features: [let]
---*/
let outside = 23;
(0,eval)('let outside;');
(0,eval)('"use strict"; let outside;');
(0,eval)('let xNonStrict = 3;');
assert.sameValue(typeof xNonStrict, 'undefined');
assert.throws(ReferenceError, function() {
xNonStrict;
});
(0,eval)('"use strict"; let xStrict = 3;');
assert.sameValue(typeof xStrict, 'undefined');
assert.throws(ReferenceError, function() {
xStrict;
});

View File

@ -0,0 +1,29 @@
// 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: >
Indirect eval code sets the new declarative environment's outer environment
to the global environment.
info: |
[...]
9. If direct is true, then
[...]
10. Else,
a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
[...]
features: [let]
---*/
var actualStrict;
var actualNonStrict;
let x = 'outside';
{
let x = 'inside';
actualNonStrict = (0,eval)('x;');
actualStrict = (0,eval)('"use strict"; x;');
}
assert.sameValue(actualNonStrict, 'outside', 'non strict mode');
assert.sameValue(actualStrict, 'outside', 'strict mode');

View File

@ -0,0 +1,24 @@
// 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: >
Indirect 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() {
(0,eval)('typeof C; class C {}');
});

View File

@ -0,0 +1,24 @@
// 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: >
Indirect 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() {
(0,eval)('typeof x; const x = null;');
});

View File

@ -0,0 +1,24 @@
// 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: >
Indirect 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() {
(0,eval)('typeof x; let x;');
});

View File

@ -0,0 +1,38 @@
// 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).
[...]
includes: [propertyHelper.js]
---*/
var initial;
(0, 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);

View File

@ -0,0 +1,44 @@
// 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).
[...]
includes: [propertyHelper.js]
---*/
var initial = null;
Object.defineProperty(this, 'f', {
enumerable: false,
writable: false,
configurable: true
});
(0, 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);

View File

@ -0,0 +1,44 @@
// 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).
[...]
includes: [propertyHelper.js]
---*/
var initial;
Object.defineProperty(this, 'f', {
enumerable: true,
writable: true,
configurable: false
});
(0,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);

View File

@ -0,0 +1,29 @@
// 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.
[...]
---*/
var initial;
(0,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');

View File

@ -0,0 +1,31 @@
// 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.
[...]
features: [let]
---*/
let x;
var caught;
// The `assert.throws` helper function would interfere with the semantics under
// test.
try {
(0,eval)('var x;');
} catch (err) {
caught = err;
}
assert.notSameValue(caught, undefined);
assert.sameValue(caught.constructor, SyntaxError);

View File

@ -0,0 +1,15 @@
// 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;
(0,eval)('"use strict"; var x;');

View File

@ -0,0 +1,20 @@
// 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 lexical binding in lower scope
info: |
[...]
5. If strict is false, then
[...]
d. Repeat while thisLex is not the same as varEnv,
[...]
features: [let]
---*/
{
let x;
{
(0,eval)('var x;');
}
}

View File

@ -0,0 +1,18 @@
// 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 lexical binding in lower scope
info: |
[...]
5. If strict is false, then
[...]
features: [let]
---*/
{
let x;
{
(0,eval)('"use strict"; var x;');
}
}

View File

@ -0,0 +1,32 @@
// 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: Declaration does not modify existing global property
info: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true).
[...]
8.1.1.4.17 CreateGlobalVarBinding
[...]
5. Let extensible be ? IsExtensible(globalObject).
6. If hasProperty is false and extensible is true, then
[...]
[...]
includes: [propertyHelper.js]
---*/
var initial;
var x = 23;
(0, eval)('initial = x; var x = 45;');
verifyEnumerable(this, 'x');
verifyWritable(this, 'x');
verifyNotConfigurable(this, 'x');
assert.sameValue(initial, 23);

View File

@ -0,0 +1,32 @@
// 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: |
[...]
16. For each String vn in declaredVarNames, in list order do
a. If varEnvRec is a global Environment Record, then
i. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true).
[...]
8.1.1.4.17 CreateGlobalVarBinding
[...]
5. Let extensible be ? IsExtensible(globalObject).
6. If hasProperty is false and extensible is true, then
a. Perform ? ObjRec.CreateMutableBinding(N, D).
b. Perform ? ObjRec.InitializeBinding(N, undefined).
[...]
includes: [propertyHelper.js]
---*/
var initial = null;
(0, eval)('initial = x; var x = 9;');
verifyEnumerable(this, 'x');
verifyWritable(this, 'x');
verifyConfigurable(this, 'x');
assert.sameValue(initial, undefined);

View File

@ -0,0 +1,23 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Error evaluating arguments list for direct eval
esid: sec-function-calls-runtime-semantics-evaluation
info: |
[...]
3. If Type(ref) is Reference and IsPropertyReference(ref) is false and
GetReferencedName(ref) is "eval", then
a. If SameValue(func, %eval%) is true, then
i. Let argList be ? ArgumentListEvaluation(Arguments).
12.3.6.1 Runtime Semantics: ArgumentListEvaluation
ArgumentList : AssignmentExpression
1. Let ref be the result of evaluating AssignmentExpression.
2. Let arg be ? GetValue(ref).
---*/
assert.throws(ReferenceError, function() {
eval(unresolvable);
});

View File

@ -0,0 +1,15 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Error evaluating arguments list for direct eval
esid: sec-function-calls-runtime-semantics-evaluation
info: |
[...]
3. If Type(ref) is Reference and IsPropertyReference(ref) is false and
GetReferencedName(ref) is "eval", then
a. If SameValue(func, %eval%) is true, then
i. Let argList be ? ArgumentListEvaluation(Arguments).
ii. If argList has no elements, return undefined.
---*/
assert.sameValue(eval(), undefined);

View File

@ -0,0 +1,30 @@
// 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 the strictness of the calling context
esid: sec-function-calls-runtime-semantics-evaluation
info: |
[...]
3. If Type(ref) is Reference and IsPropertyReference(ref) is false and
GetReferencedName(ref) is "eval", then
a. If SameValue(func, %eval%) is true, then
[...]
iv. If the source code matching this CallExpression is strict code,
let strictCaller be true. Otherwise let strictCaller be false.
[...]
flags: [noStrict]
---*/
var count = 0;
eval('var static; count += 1;');
assert.sameValue(count, 1);
eval('with ({}) {} count += 1;');
assert.sameValue(count, 2);
eval('unresolvable = null; count += 1;');
assert.sameValue(count, 3);

View File

@ -0,0 +1,28 @@
// 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 the strictness of the calling context
esid: sec-function-calls-runtime-semantics-evaluation
info: |
[...]
3. If Type(ref) is Reference and IsPropertyReference(ref) is false and
GetReferencedName(ref) is "eval", then
a. If SameValue(func, %eval%) is true, then
[...]
iv. If the source code matching this CallExpression is strict code,
let strictCaller be true. Otherwise let strictCaller be false.
[...]
flags: [onlyStrict]
---*/
assert.throws(SyntaxError, function() {
eval('var static;');
});
assert.throws(SyntaxError, function() {
eval('with ({}) {}');
});
assert.throws(ReferenceError, function() {
eval('unresolvable = null;');
});