diff --git a/test/language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-function-declaration.js b/test/language/global-code/decl-func-dup.js similarity index 77% rename from test/language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-function-declaration.js rename to test/language/global-code/decl-func-dup.js index e5ef31b88b..ee808a3712 100644 --- a/test/language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-function-declaration.js +++ b/test/language/global-code/decl-func-dup.js @@ -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); diff --git a/test/language/global-code/decl-func.js b/test/language/global-code/decl-func.js new file mode 100644 index 0000000000..1a4181a2fa --- /dev/null +++ b/test/language/global-code/decl-func.js @@ -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() {} diff --git a/test/language/global-code/decl-lex-configurable-global.js b/test/language/global-code/decl-lex-configurable-global.js new file mode 100644 index 0000000000..52465fdace --- /dev/null +++ b/test/language/global-code/decl-lex-configurable-global.js @@ -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'); diff --git a/test/language/global-code/decl-lex-deletion.js b/test/language/global-code/decl-lex-deletion.js new file mode 100644 index 0000000000..1b6421cfe9 --- /dev/null +++ b/test/language/global-code/decl-lex-deletion.js @@ -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; diff --git a/test/language/global-code/decl-lex-restricted-global.js b/test/language/global-code/decl-lex-restricted-global.js new file mode 100644 index 0000000000..7e32fca82a --- /dev/null +++ b/test/language/global-code/decl-lex-restricted-global.js @@ -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; diff --git a/test/language/global-code/decl-lex.js b/test/language/global-code/decl-lex.js new file mode 100644 index 0000000000..0884b6c2f5 --- /dev/null +++ b/test/language/global-code/decl-lex.js @@ -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)' +); diff --git a/test/language/global-code/decl-var.js b/test/language/global-code/decl-var.js new file mode 100644 index 0000000000..4b652858ef --- /dev/null +++ b/test/language/global-code/decl-var.js @@ -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; diff --git a/test/language/global-code/script-decl-func-dups.js b/test/language/global-code/script-decl-func-dups.js new file mode 100644 index 0000000000..b94b156997 --- /dev/null +++ b/test/language/global-code/script-decl-func-dups.js @@ -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); diff --git a/test/language/global-code/script-decl-func-err-non-configurable.js b/test/language/global-code/script-decl-func-err-non-configurable.js new file mode 100644 index 0000000000..9810c814ef --- /dev/null +++ b/test/language/global-code/script-decl-func-err-non-configurable.js @@ -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'); diff --git a/test/language/global-code/script-decl-func-err-non-extensible.js b/test/language/global-code/script-decl-func-err-non-extensible.js new file mode 100644 index 0000000000..f0fe045e7e --- /dev/null +++ b/test/language/global-code/script-decl-func-err-non-extensible.js @@ -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); diff --git a/test/language/global-code/script-decl-func.js b/test/language/global-code/script-decl-func.js new file mode 100644 index 0000000000..101b969c9a --- /dev/null +++ b/test/language/global-code/script-decl-func.js @@ -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'); diff --git a/test/language/global-code/script-decl-lex-deletion.js b/test/language/global-code/script-decl-lex-deletion.js new file mode 100644 index 0000000000..abad9c4627 --- /dev/null +++ b/test/language/global-code/script-decl-lex-deletion.js @@ -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; diff --git a/test/language/global-code/script-decl-lex-lex.js b/test/language/global-code/script-decl-lex-lex.js new file mode 100644 index 0000000000..13afba6dca --- /dev/null +++ b/test/language/global-code/script-decl-lex-lex.js @@ -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'); diff --git a/test/language/global-code/script-decl-lex-restricted-global.js b/test/language/global-code/script-decl-lex-restricted-global.js new file mode 100644 index 0000000000..ca7f5b562f --- /dev/null +++ b/test/language/global-code/script-decl-lex-restricted-global.js @@ -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; +}); diff --git a/test/language/global-code/script-decl-lex-var.js b/test/language/global-code/script-decl-lex-var.js new file mode 100644 index 0000000000..e6666b8125 --- /dev/null +++ b/test/language/global-code/script-decl-lex-var.js @@ -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)'); diff --git a/test/language/global-code/script-decl-lex.js b/test/language/global-code/script-decl-lex.js new file mode 100644 index 0000000000..e10e7b0394 --- /dev/null +++ b/test/language/global-code/script-decl-lex.js @@ -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)' +); diff --git a/test/language/global-code/script-decl-var-collision.js b/test/language/global-code/script-decl-var-collision.js new file mode 100644 index 0000000000..37df494eb9 --- /dev/null +++ b/test/language/global-code/script-decl-var-collision.js @@ -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)'); diff --git a/test/language/global-code/script-decl-var-err.js b/test/language/global-code/script-decl-var-err.js new file mode 100644 index 0000000000..f6331889a8 --- /dev/null +++ b/test/language/global-code/script-decl-var-err.js @@ -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); diff --git a/test/language/global-code/script-decl-var.js b/test/language/global-code/script-decl-var.js new file mode 100644 index 0000000000..791b1e65be --- /dev/null +++ b/test/language/global-code/script-decl-var.js @@ -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');