Add tests for script interactions (#689)

ECMA262 allows for an arbitrary number of "ScriptJob"s to run in a given realm.
Although there is no standard mechanism for enqueuing these jobs, many
implementations offer this functionality through custom APIs. In those hosts,
the semantics describing script interactions are directly observable.
In order to guarantee conformance to the specification in advance of a
standardized API, Test262 now requires that hosts provide a $.evalScript
function whose behavior is defined in the project's "INTERPRETING.md" file.
Use this host-provided API to ensure that implementations correctly observe the
specification text that dictates script interactions.
(In writing these tests, I noticed some gaps in coverage that are observable
from a single script execution. This patch includes a dedicated commit for
these tests that do not require $.evalScript.)

* Improve coverage of GlobalDeclarationInstantiation

* Add tests for script interactions

Use the host-provied `$.evalScript` method to assert conformance to the
specification text that defines script interactions.

* fixup! Improve coverage of GlobalDeclarationInstantiation
This commit is contained in:
jugglinmike 2016-07-19 21:02:05 -04:00 committed by Tom Care
parent e3ae1c88ff
commit b9e21138cc
19 changed files with 858 additions and 1 deletions

View File

@ -6,5 +6,6 @@ description: >
redeclaration outermost:
allowed to redeclare function declaration with function declaration
---*/
function f() {} function f() {}
function f() { return 1; } function f() { return 2; }
assert.sameValue(f(), 2);

View File

@ -0,0 +1,48 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of function where permissible
info: |
[...]
9. Let declaredFunctionNames be a new empty List.
10. 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.
ii. NOTE If there are multiple FunctionDeclarations for the same name,
the last declaration is used.
iii. Let fn be the sole element of the BoundNames of d.
iv. If fn is not an element of declaredFunctionNames, then
1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
2. If fnDefinable is false, throw a TypeError exception.
3. Append fn to declaredFunctionNames.
4. Insert d as the first element of functionsToInitialize.
[...]
17. 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 env.
c. Perform ? envRec.CreateGlobalFunctionBinding(fn, fo, false).
[...]
8.1.1.4.16 CanDeclareGlobalFunction
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
5. If existingProp is undefined, return ? IsExtensible(globalObject).
includes: [propertyHelper.js]
---*/
assert.sameValue(
typeof brandNew, 'function', 'new binding on an extensible global object'
);
verifyEnumerable(this, 'brandNew');
verifyWritable(this, 'brandNew');
verifyNotConfigurable(this, 'brandNew');
function brandNew() {}

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Lexical declarations "shadow" configurable global properties
info: |
[...]
5. For each name in lexNames, do
[...]
c. Let hasRestrictedGlobal be ? envRec.HasRestrictedGlobalProperty(name).
d. If hasRestrictedGlobal is true, throw a SyntaxError exception.
[...]
16. 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 ? envRec.CreateImmutableBinding(dn, true).
ii. Else,
1. Perform ? envRec.CreateMutableBinding(dn, false).
includes: [propertyHelper.js]
---*/
let Array;
assert.sameValue(Array, undefined);
assert.sameValue(typeof this.Array, 'function');
verifyNotEnumerable(this, 'Array');
verifyWritable(this, 'Array');
verifyConfigurable(this, 'Array');

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Globally-declared lexical bindings cannot be deleted
info: |
[...]
16. 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 ? envRec.CreateImmutableBinding(dn, true).
ii. Else,
1. Perform ? envRec.CreateMutableBinding(dn, false).
[...]
flags: [noStrict]
---*/
let test262let;
delete test262let;
// Binding values are asserted by a dedicated test. IdentifierReferences serve
// to ensure that the entries in the environment record persist.
test262let;
const test262const = null;
delete test262const;
test262const;
class test262class {}
delete test262class;
test262class;

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Lexical declaration collides with existing "restricted global"
info: |
[...]
5. For each name in lexNames, do
[...]
c. Let hasRestrictedGlobal be ? envRec.HasRestrictedGlobalProperty(name).
d. If hasRestrictedGlobal is true, throw a SyntaxError exception.
negative: SyntaxError
---*/
let undefined;

View File

@ -0,0 +1,52 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of lexical bindings
info: |
[...]
16. 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 ? envRec.CreateImmutableBinding(dn, true).
ii. Else,
1. Perform ? envRec.CreateMutableBinding(dn, false).
[...]
---*/
let test262let = 1;
test262let = 2;
assert.sameValue(test262let, 2, '`let` binding is mutable');
assert.sameValue(
this.hasOwnProperty('test262let'),
false,
'property not created on the global object (let)'
);
const test262const = 3;
assert.throws(TypeError, function() {
test262const = 4;
}, '`const` binding is strictly immutable');
assert.sameValue(test262const, 3, '`const` binding cannot be modified');
assert.sameValue(
this.hasOwnProperty('test262const'),
false,
'property not created on the global object (const)'
);
class test262class {}
test262class = 5;
assert.sameValue(test262class, 5, '`class` binding is mutable');
assert.sameValue(
this.hasOwnProperty('test262class'),
false,
'property not created on the global object (class)'
);

View File

@ -0,0 +1,42 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of variable where permissible
info: |
[...]
11. Let declaredVarNames be a new empty List.
12. For each d in varDeclarations, do
a. If d is a VariableDeclaration or a ForBinding, then
i. For each String vn in the BoundNames of d, do
1. If vn is not an element of declaredFunctionNames, then
a. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn).
b. If vnDefinable is false, throw a TypeError exception.
c. If vn is not an element of declaredVarNames, then
i. Append vn to declaredVarNames.
[...]
18. For each String vn in declaredVarNames, in list order do
a. Perform ? envRec.CreateGlobalVarBinding(vn, false).
[...]
8.1.1.4.15 CanDeclareGlobalVar
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let hasProperty be ? HasOwnProperty(globalObject, N).
5. If hasProperty is true, return true.
6. Return ? IsExtensible(globalObject).
includes: [propertyHelper.js]
---*/
assert.sameValue(
this.brandNew, undefined, 'new binding on an extensible global object'
);
verifyEnumerable(this, 'brandNew');
verifyWritable(this, 'brandNew');
verifyNotConfigurable(this, 'brandNew');
var brandNew;

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-globaldeclarationinstantiation
es6id: 15.1.8
description: >
When multiple like-named function declarations exist, the final is assigned
to the new binding.
info: |
[...]
9. Let declaredFunctionNames be a new empty List.
10. 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.
ii. NOTE If there are multiple FunctionDeclarations for the same name,
the last declaration is used.
iii. Let fn be the sole element of the BoundNames of d.
iv. If fn is not an element of declaredFunctionNames, then
1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
2. If fnDefinable is false, throw a TypeError exception.
3. Append fn to declaredFunctionNames.
4. Insert d as the first element of functionsToInitialize.
[...]
---*/
$.evalScript(
'function f() { return 1; }' +
'function f() { return 2; }' +
'function f() { return 3; }'
);
assert.sameValue(f(), 3);

View File

@ -0,0 +1,105 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: >
Declaration of function when there is a corresponding global property that is
non-configurable but *not* a writable and configurable data property.
info: |
[...]
9. Let declaredFunctionNames be a new empty List.
10. 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.
ii. NOTE If there are multiple FunctionDeclarations for the same name,
the last declaration is used.
iii. Let fn be the sole element of the BoundNames of d.
iv. If fn is not an element of declaredFunctionNames, then
1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
2. If fnDefinable is false, throw a TypeError exception.
8.1.1.4.16 CanDeclareGlobalFunction
[...]
6. If existingProp.[[Configurable]] is true, return true.
7. If IsDataDescriptor(existingProp) is true and existingProp has attribute
values {[[Writable]]: true, [[Enumerable]]: true}, return true.
8. Return false.
---*/
Object.defineProperty(
this,
'data1',
{ configurable: false, value: 0, writable: true, enumerable: false }
);
Object.defineProperty(
this,
'data2',
{ configurable: false, value: 0, writable: false, enumerable: true }
);
Object.defineProperty(
this,
'data3',
{ configurable: false, value: 0, writable: false, enumerable: false }
);
Object.defineProperty(
this,
'accessor1',
{
configurable: false,
get: function() {},
set: function() {},
enumerable: true
}
);
Object.defineProperty(
this,
'accessor2',
{
configurable: false,
get: function() {},
set: function() {},
enumerable: true
}
);
assert.throws(TypeError, function() {
$.evalScript('var x; function data1() {}');
}, 'writable, non-enumerable data property');
assert.throws(ReferenceError, function() {
x;
}, 'bindings not created for writable, non-enumerable data property');
assert.throws(TypeError, function() {
$.evalScript('var x; function data2() {}');
}, 'non-writable, enumerable data property');
assert.throws(ReferenceError, function() {
x;
}, 'bindings not created for non-writable, enumerable data property');
assert.throws(TypeError, function() {
$.evalScript('var x; function data3() {}');
}, 'non-writable, non-enumerable data property');
assert.throws(ReferenceError, function() {
x;
}, 'bindings not created for non-writable, non-enumerable data property');
assert.throws(TypeError, function() {
$.evalScript('var x; function accessor1() {}');
}, 'enumerable accessor property');
assert.throws(ReferenceError, function() {
x;
}, 'bindings not created for enumerableaccessor property');
assert.throws(TypeError, function() {
$.evalScript('var x; function accessor2() {}');
}, 'non-enumerable accessor property');
assert.throws(ReferenceError, function() {
x;
}, 'bindings not created for non-enumerableaccessor property');

View File

@ -0,0 +1,41 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: >
Declaration of function when there is no corresponding global property and
the global object is non-extensible
info: |
[...]
9. Let declaredFunctionNames be a new empty List.
10. 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.
ii. NOTE If there are multiple FunctionDeclarations for the same name,
the last declaration is used.
iii. Let fn be the sole element of the BoundNames of d.
iv. If fn is not an element of declaredFunctionNames, then
1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
2. If fnDefinable is false, throw a TypeError exception.
8.1.1.4.16 CanDeclareGlobalFunction
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
5. If existingProp is undefined, return ? IsExtensible(globalObject).
---*/
var executed = false;
Object.preventExtensions(this);
assert.throws(TypeError, function() {
$.evalScript('executed = true; function test262() {}');
});
assert.sameValue(executed, false);

View File

@ -0,0 +1,79 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of function where permissible
info: |
[...]
9. Let declaredFunctionNames be a new empty List.
10. 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.
ii. NOTE If there are multiple FunctionDeclarations for the same name,
the last declaration is used.
iii. Let fn be the sole element of the BoundNames of d.
iv. If fn is not an element of declaredFunctionNames, then
1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn).
2. If fnDefinable is false, throw a TypeError exception.
3. Append fn to declaredFunctionNames.
4. Insert d as the first element of functionsToInitialize.
[...]
17. 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 env.
c. Perform ? envRec.CreateGlobalFunctionBinding(fn, fo, false).
[...]
8.1.1.4.16 CanDeclareGlobalFunction
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
5. If existingProp is undefined, return ? IsExtensible(globalObject).
includes: [propertyHelper.js]
---*/
$.evalScript('function brandNew() {}');
assert.sameValue(
typeof brandNew, 'function', 'new binding on an extensible global object'
);
verifyEnumerable(this, 'brandNew');
verifyWritable(this, 'brandNew');
verifyNotConfigurable(this, 'brandNew');
Object.defineProperty(this, 'configurable', { configurable: true, value: 0 });
Object.defineProperty(
this,
'nonConfigurable',
{ configurable: false, writable: true, enumerable: true, value: 0 }
);
// Prevent extensions on the global object to ensure that detail is not
// considered by any of the declarations which follow.
Object.preventExtensions(this);
$.evalScript('function configurable() {}');
assert.sameValue(
typeof configurable, 'function', 'like-named configurable property'
);
verifyEnumerable(this, 'configurable')
verifyWritable(this, 'configurable');
verifyNotConfigurable(this, 'configurable');
$.evalScript('function nonConfigurable() {}');
assert.sameValue(
typeof nonConfigurable,
'function',
'like-named non-configurable data property that is writable and enumerable'
);
verifyEnumerable(this, 'nonConfigurable');
verifyWritable(this, 'nonConfigurable');
verifyNotConfigurable(this, 'nonConfigurable');

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Globally-declared lexical bindings cannot be deleted
info: |
[...]
16. 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 ? envRec.CreateImmutableBinding(dn, true).
ii. Else,
1. Perform ? envRec.CreateMutableBinding(dn, false).
[...]
flags: [noStrict]
---*/
$.evalScript('let test262let;');
delete test262let;
// Binding values are asserted by a dedicated test. IdentifierReferences serve
// to ensure that the entries in the environment record persist.
test262let;
$.evalScript('const test262const = null;');
delete test262const;
test262const;
$.evalScript('class test262class {}');
delete test262class;
test262class;

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Let binding collision with existing lexical declaration
info: |
[...]
5. For each name in lexNames, do
a. If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
exception.
b. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
exception.
---*/
let test262Let;
const test262Const = null;
class test262Class {}
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262Let;');
}, '`let` binding');
assert.throws(ReferenceError, function() {
x;
}, 'No bindings created for script containing `let` redeclaration');
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262Const;');
}, '`const` binding');
assert.throws(ReferenceError, function() {
x;
}, 'No bindings created for script containing `const` redeclaration');
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262Class;');
}, '`class` binding');
assert.throws(ReferenceError, function() {
x;
}, 'No bindings created for script containing `class` redeclaration');

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-globaldeclarationinstantiation
es6id: 15.1.8
description: >
Let binding collision with non-configurable global property (not defined
through a declaration)
info: |
[...]
5. For each name in lexNames, do
a. If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
exception.
b. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
exception.
c. Let hasRestrictedGlobal be ? envRec.HasRestrictedGlobalProperty(name).
d. If hasRestrictedGlobal is true, throw a SyntaxError exception.
---*/
Object.defineProperty(this, 'test262Configurable', { configurable: true });
Object.defineProperty(this, 'test262NonConfigurable', { configurable: false });
$.evalScript('let test262Configurable;');
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262NonConfigurable;');
});
assert.throws(ReferenceError, function() {
x;
});

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-globaldeclarationinstantiation
es6id: 15.1.8
description: Let binding collision with existing var declaration
info: |
[...]
5. For each name in lexNames, do
a. If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
exception.
---*/
var test262Var;
function test262Fn() {}
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262Var;');
}, 'variable');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script shadowing variable)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; let test262Fn;');
}, 'function');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script shadowing function)');

View File

@ -0,0 +1,56 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of lexical bindings
info: |
[...]
16. 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 ? envRec.CreateImmutableBinding(dn, true).
ii. Else,
1. Perform ? envRec.CreateMutableBinding(dn, false).
[...]
---*/
// Extensibility of the global object should have no bearing on lexical
// declarations.
Object.preventExtensions(this);
$.evalScript('let test262let = 1;');
test262let = 2;
assert.sameValue(test262let, 2, '`let` binding is mutable');
assert.sameValue(
this.hasOwnProperty('test262let'),
false,
'property not created on the global object (let)'
);
$.evalScript('const test262const = 3;');
assert.throws(TypeError, function() {
test262const = 4;
}, '`const` binding is strictly immutable');
assert.sameValue(test262const, 3, '`const` binding cannot be modified');
assert.sameValue(
this.hasOwnProperty('test262const'),
false,
'property not created on the global object (const)'
);
$.evalScript('class test262class {}');
test262class = 5;
assert.sameValue(test262class, 5, '`class` binding is mutable');
assert.sameValue(
this.hasOwnProperty('test262class'),
false,
'property not created on the global object (class)'
);

View File

@ -0,0 +1,62 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Var binding collision with existing lexical declaration
info: |
[...]
6. For each name in varNames, do
a. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
exception.
---*/
var test262Var;
let test262Let;
const test262Const = null;
class test262Class {}
$.evalScript('var test262Var;');
$.evalScript('function test262Var() {}');
assert.throws(SyntaxError, function() {
$.evalScript('var x; var test262Let;');
}, '`var` on `let` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a `var` on a `let` binding)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; var test262Const;');
}, '`var` on `const` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a `var` on a `const` binding)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; var test262Class;');
}, '`var` on `class` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a `var` on a `class` binding)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; function test262Let() {}');
}, 'function on `let` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a function on a `let` binding)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; function test262Const() {}');
}, 'function on `const` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a function on a `const` binding)');
assert.throws(SyntaxError, function() {
$.evalScript('var x; function test262Class() {}');
} , 'function on `class` binding');
assert.throws(ReferenceError, function() {
x;
}, 'no bindings created (script declaring a function on a class binding)');

View File

@ -0,0 +1,40 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: >
Declaration of variable when there is no corresponding global property and
the global object is non-extensible
info: |
[...]
11. Let declaredVarNames be a new empty List.
12. For each d in varDeclarations, do
a. If d is a VariableDeclaration or a ForBinding, then
i. For each String vn in the BoundNames of d, do
1. If vn is not an element of declaredFunctionNames, then
a. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn).
b. If vnDefinable is false, throw a TypeError exception.
c. If vn is not an element of declaredVarNames, then
i. Append vn to declaredVarNames.
8.1.1.4.15 CanDeclareGlobalVar
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let hasProperty be ? HasOwnProperty(globalObject, N).
5. If hasProperty is true, return true.
6. Return ? IsExtensible(globalObject).
---*/
var executed = false;
Object.preventExtensions(this);
assert.throws(TypeError, function() {
$.evalScript('executed = true; var test262;');
});
assert.sameValue(executed, false);

View File

@ -0,0 +1,71 @@
// 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-globaldeclarationinstantiation
es6id: 15.1.8
description: Declaration of variable where permissible
info: |
[...]
11. Let declaredVarNames be a new empty List.
12. For each d in varDeclarations, do
a. If d is a VariableDeclaration or a ForBinding, then
i. For each String vn in the BoundNames of d, do
1. If vn is not an element of declaredFunctionNames, then
a. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn).
b. If vnDefinable is false, throw a TypeError exception.
c. If vn is not an element of declaredVarNames, then
i. Append vn to declaredVarNames.
[...]
18. For each String vn in declaredVarNames, in list order do
a. Perform ? envRec.CreateGlobalVarBinding(vn, false).
[...]
8.1.1.4.15 CanDeclareGlobalVar
1. Let envRec be the global Environment Record for which the method was
invoked.
2. Let ObjRec be envRec.[[ObjectRecord]].
3. Let globalObject be the binding object for ObjRec.
4. Let hasProperty be ? HasOwnProperty(globalObject, N).
5. If hasProperty is true, return true.
6. Return ? IsExtensible(globalObject).
includes: [propertyHelper.js]
---*/
$.evalScript('var brandNew;');
assert.sameValue(
this.brandNew, undefined, 'new binding on an extensible global object'
);
verifyEnumerable(this, 'brandNew');
verifyWritable(this, 'brandNew');
verifyNotConfigurable(this, 'brandNew');
Object.defineProperty(
this,
'configurable',
{ configurable: true, writable: false, enumerable: false, value: 0 }
);
Object.defineProperty(
this,
'nonConfigurable',
{ configurable: false, writable: false, enumerable: false, value: 0 }
);
// Prevent extensions on the global object to ensure that detail is not
// considered by any of the declarations which follow.
Object.preventExtensions(this);
$.evalScript('var configurable;');
assert.sameValue(configurable, 0, 'like-named configurable property');
verifyNotEnumerable(this, 'configurable');
verifyNotWritable(this, 'configurable');
verifyConfigurable(this, 'configurable');
$.evalScript('var nonConfigurable;');
assert.sameValue(nonConfigurable, 0, 'like-named non-configurable property');
verifyNotEnumerable(this, 'nonConfigurable');
verifyNotWritable(this, 'nonConfigurable');
verifyNotConfigurable(this, 'nonConfigurable');