diff --git a/test/language/expressions/arrow-function/scope-body-lex-distinct.js b/test/language/expressions/arrow-function/scope-body-lex-distinct.js new file mode 100644 index 0000000000..9416b7fdc3 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-body-lex-distinct.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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var a = () => { let x; eval('var x;'); }; + +assert.throws(SyntaxError, a); diff --git a/test/language/expressions/arrow-function/scope-param-elem-var-close.js b/test/language/expressions/arrow-function/scope-param-elem-var-close.js new file mode 100644 index 0000000000..bcb987ebb9 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-param-elem-var-close.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +(( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) => { + probeBody = function() { return x; }; +})(); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/arrow-function/scope-param-elem-var-open.js b/test/language/expressions/arrow-function/scope-param-elem-var-open.js new file mode 100644 index 0000000000..7f60a06102 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) => { +})(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/arrow-function/scope-param-rest-elem-var-close.js b/test/language/expressions/arrow-function/scope-param-rest-elem-var-close.js new file mode 100644 index 0000000000..976565a989 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-param-rest-elem-var-close.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +(( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) => { + probeBody = function() { return x; } +})(); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/arrow-function/scope-param-rest-elem-var-open.js b/test/language/expressions/arrow-function/scope-param-rest-elem-var-open.js new file mode 100644 index 0000000000..b7a88bc050 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-param-rest-elem-var-open.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) => { +})(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/arrow-function/scope-paramsbody-var-close.js b/test/language/expressions/arrow-function/scope-paramsbody-var-close.js new file mode 100644 index 0000000000..a0472fc272 --- /dev/null +++ b/test/language/expressions/arrow-function/scope-paramsbody-var-close.js @@ -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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +// A parameter expression is necessary to trigger the creation of the scope +// under test. +((_ = null) => { + var x = 'inside'; + probe = function() { return x; }; +})(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/arrow-function/scope-paramsbody-var-open.js b/test/language/expressions/arrow-function/scope-paramsbody-var-open.js new file mode 100644 index 0000000000..c0bc7669fa --- /dev/null +++ b/test/language/expressions/arrow-function/scope-paramsbody-var-open.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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +((_ = probeParams = function() { return x; }) => { + var x = 'inside'; + probeBody = function() { return x; }; +})(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/call/scope-lex-close.js b/test/language/expressions/call/scope-lex-close.js new file mode 100644 index 0000000000..a9f048cbc7 --- /dev/null +++ b/test/language/expressions/call/scope-lex-close.js @@ -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-ecmascript-function-objects-call-thisargument-argumentslist +description: > + Removal of lexical environment for the function parameters and body +info: | + [...] + 3. Let callerContext be the running execution context. + [...] + 8. Remove calleeContext from the execution context stack and restore + callerContext as the running execution context. + [...] +features: [let] +---*/ + +var probe; + +// This test intentionally elides parameter expressions because their presence +// triggers the creation of an additional LexicalEnvironment dedicated to the +// function body (see sec-functiondeclarationinstantiation) +(function() { + let x = 'inside'; + probe = function() { return x; }; +}()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/call/scope-lex-open.js b/test/language/expressions/call/scope-lex-open.js new file mode 100644 index 0000000000..9f1e2cc1af --- /dev/null +++ b/test/language/expressions/call/scope-lex-open.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-ecmascript-function-objects-call-thisargument-argumentslist +description: > + Creation of new variable environment for the function parameters and body + (as disinct from that for the function's BindingIdentifier) +info: | + [...] + 3. Let callerContext be the running execution context. + 4. Let calleeContext be PrepareForOrdinaryCall(F, undefined). + [...] + + 9.2.1.1 PrepareForOrdinaryCall + + [...] + 8. Let localEnv be NewFunctionEnvironment(F, newTarget). + 9. Set the LexicalEnvironment of calleeContext to localEnv. + 10. Set the VariableEnvironment of calleeContext to localEnv. + [...] +features: [let] +---*/ + +var name = 'outside'; +var probeBefore = function() { return name; }; +var probeInside; + +// This test intentionally elides parameter expressions because their presence +// triggers the creation of an additional LexicalEnvironment dedicated to the +// function body (see sec-functiondeclarationinstantiation) +var func = function name() { + let name = 'inside'; + probeInside = function() { return name; }; +}; + +func(); + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeInside(), 'inside'); diff --git a/test/language/expressions/call/scope-var-close.js b/test/language/expressions/call/scope-var-close.js new file mode 100644 index 0000000000..5a76a49ea5 --- /dev/null +++ b/test/language/expressions/call/scope-var-close.js @@ -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-prepareforordinarycall +description: > + Removal of variable environment for the function parameters and body +info: | + [...] + 3. Let callerContext be the running execution context. + [...] + 8. Remove calleeContext from the execution context stack and restore + callerContext as the running execution context. + [...] +---*/ + +var probe; + +// This test intentionally elides parameter expressions because their presence +// triggers the creation of an additional LexicalEnvironment dedicated to the +// function body (see sec-functiondeclarationinstantiation) +(function() { + var x = 'inside'; + probe = function() { return x; }; +}()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/call/scope-var-open.js b/test/language/expressions/call/scope-var-open.js new file mode 100644 index 0000000000..a50cc1e2c9 --- /dev/null +++ b/test/language/expressions/call/scope-var-open.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-prepareforordinarycall +description: > + Creation of new variable environment for the function parameters and body + (as disinct from that for the function's BindingIdentifier) +info: | + [...] + 3. Let callerContext be the running execution context. + 4. Let calleeContext be PrepareForOrdinaryCall(F, undefined). + [...] + + 9.2.1.1 PrepareForOrdinaryCall + + [...] + 8. Let localEnv be NewFunctionEnvironment(F, newTarget). + 9. Set the LexicalEnvironment of calleeContext to localEnv. + 10. Set the VariableEnvironment of calleeContext to localEnv. + [...] +---*/ + +var name = 'outside'; +var probeBefore = function() { return name; }; +var probeBody; + +// This test intentionally elides parameter expressions because their presence +// triggers the creation of an additional LexicalEnvironment dedicated to the +// function body (see sec-functiondeclarationinstantiation) +var func = function name() { + // The initializer is intentionally omitted from the following + // VariableStatement in order to demonstrate that a new binding is created + // (and not simply re-used from the FunctionExpression's BindingIdentifier). + var name; + probeBody = function() { return name; }; +}; + +func(); + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeBody(), undefined); diff --git a/test/language/expressions/class/scope-gen-meth-paramsbody-var-close.js b/test/language/expressions/class/scope-gen-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..d0f4280f8f --- /dev/null +++ b/test/language/expressions/class/scope-gen-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + *m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.prototype.m().next(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-gen-meth-paramsbody-var-open.js b/test/language/expressions/class/scope-gen-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..1b09a356e9 --- /dev/null +++ b/test/language/expressions/class/scope-gen-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class{ + *m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.prototype.m().next(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/class/scope-meth-paramsbody-var-close.js b/test/language/expressions/class/scope-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..b3b9a67fa7 --- /dev/null +++ b/test/language/expressions/class/scope-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.prototype.m(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-meth-paramsbody-var-open.js b/test/language/expressions/class/scope-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..843a8b6d3e --- /dev/null +++ b/test/language/expressions/class/scope-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class { + m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.prototype.m(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/class/scope-name-lex-close.js b/test/language/expressions/class/scope-name-lex-close.js new file mode 100644 index 0000000000..4776a1e314 --- /dev/null +++ b/test/language/expressions/class/scope-name-lex-close.js @@ -0,0 +1,21 @@ +// 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-runtime-semantics-classdefinitionevaluation +description: Removal of lexical environment for class "name" +info: | + [...] + 22. Set the running execution context's LexicalEnvironment to lex. + [...] +---*/ + +var C = 'outside'; + +var cls = class C { + method() { + return C; + } +}; + +assert.sameValue(cls.prototype.method(), cls, 'from instance method'); +assert.sameValue(C, 'outside'); diff --git a/test/language/expressions/class/scope-name-lex-open-heritage.js b/test/language/expressions/class/scope-name-lex-open-heritage.js new file mode 100644 index 0000000000..e7d16fb498 --- /dev/null +++ b/test/language/expressions/class/scope-name-lex-open-heritage.js @@ -0,0 +1,37 @@ +// 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-runtime-semantics-classdefinitionevaluation +description: > + Creation of new lexical environment for the class "name" (with a heritage) +info: | + 1. Let lex be the LexicalEnvironment of the running execution context. + 2. Let classScope be NewDeclarativeEnvironment(lex). + 3. Let classScopeEnvRec be classScope's EnvironmentRecord. + 4. If className is not undefined, then + a. Perform classScopeEnvRec.CreateImmutableBinding(className, true). + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + a. Set the running execution context's LexicalEnvironment to classScope. + [...] +---*/ + +var probeBefore = function() { return C; }; +var probeHeritage, setHeritage; +var C = 'outside'; + +var cls = class C extends ( + probeHeritage = function() { return C; }, + setHeritage = function() { C = null; } + ) { + method() { + return C; + } +}; + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeHeritage(), cls, 'from class heritage'); +assert.throws(TypeError, setHeritage, 'inner binding rejects modification'); +assert.sameValue(probeHeritage(), cls, 'inner binding is immutable'); +assert.sameValue(cls.prototype.method(), cls, 'from instance method'); diff --git a/test/language/expressions/class/scope-name-lex-open-no-heritage.js b/test/language/expressions/class/scope-name-lex-open-no-heritage.js new file mode 100644 index 0000000000..2717b51b58 --- /dev/null +++ b/test/language/expressions/class/scope-name-lex-open-no-heritage.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-runtime-semantics-classdefinitionevaluation +description: > + Creation of new lexical environment for the class "name" (without a + heritage) +info: | + 1. Let lex be the LexicalEnvironment of the running execution context. + 2. Let classScope be NewDeclarativeEnvironment(lex). + 3. Let classScopeEnvRec be classScope's EnvironmentRecord. + 4. If className is not undefined, then + a. Perform classScopeEnvRec.CreateImmutableBinding(className, true). + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + a. Set the running execution context's LexicalEnvironment to classScope. + [...] + 11. Set the running execution context's LexicalEnvironment to classScope. +---*/ + +var probeBefore = function() { return C; }; +var C = 'outside'; + +var cls = class C { + probe() { + return C; + } + modify() { + C = null; + } +}; + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(cls.prototype.probe(), cls, 'inner binding value'); +assert.throws( + TypeError, cls.prototype.modify, 'inner binding rejects modification' +); +assert.sameValue(cls.prototype.probe(), cls, 'inner binding is immutable'); diff --git a/test/language/expressions/class/scope-setter-paramsbody-var-close.js b/test/language/expressions/class/scope-setter-paramsbody-var-close.js new file mode 100644 index 0000000000..9d025c2230 --- /dev/null +++ b/test/language/expressions/class/scope-setter-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + set a(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.prototype.a = null; + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-setter-paramsbody-var-open.js b/test/language/expressions/class/scope-setter-paramsbody-var-open.js new file mode 100644 index 0000000000..46db7ba16b --- /dev/null +++ b/test/language/expressions/class/scope-setter-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class { + set a(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.prototype.a = undefined; + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-close.js b/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..26ef25edc8 --- /dev/null +++ b/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static *m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.m().next(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-open.js b/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..17167c3ce4 --- /dev/null +++ b/test/language/expressions/class/scope-static-gen-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class { + static *m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.m().next(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/class/scope-static-meth-paramsbody-var-close.js b/test/language/expressions/class/scope-static-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..6b55004eac --- /dev/null +++ b/test/language/expressions/class/scope-static-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.m(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-static-meth-paramsbody-var-open.js b/test/language/expressions/class/scope-static-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..44dfe39d76 --- /dev/null +++ b/test/language/expressions/class/scope-static-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class { + static m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.m(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/class/scope-static-setter-paramsbody-var-close.js b/test/language/expressions/class/scope-static-setter-paramsbody-var-close.js new file mode 100644 index 0000000000..1ded6d1b4e --- /dev/null +++ b/test/language/expressions/class/scope-static-setter-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +var C = class { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static set a(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}; +C.a = null; + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/class/scope-static-setter-paramsbody-var-open.js b/test/language/expressions/class/scope-static-setter-paramsbody-var-open.js new file mode 100644 index 0000000000..5f01fdbe5d --- /dev/null +++ b/test/language/expressions/class/scope-static-setter-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +var C = class { + static set a(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}; +C.a = undefined; + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/function/scope-body-lex-distinct.js b/test/language/expressions/function/scope-body-lex-distinct.js new file mode 100644 index 0000000000..3fbaa973c9 --- /dev/null +++ b/test/language/expressions/function/scope-body-lex-distinct.js @@ -0,0 +1,49 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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;'); +}); diff --git a/test/language/expressions/function/scope-name-var-close.js b/test/language/expressions/function/scope-name-var-close.js new file mode 100644 index 0000000000..c119ca2771 --- /dev/null +++ b/test/language/expressions/function/scope-name-var-close.js @@ -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-function-definitions-runtime-semantics-evaluation +description: Removal of variable environment for the BindingIdentifier +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, + funcEnv, strict). + [...] +---*/ + +var probe; + +var func = function f() { + probe = function() { return f; }; +}; +var f = 'outside'; + +func(); + +assert.sameValue(f, 'outside'); +assert.sameValue(probe(), func); diff --git a/test/language/expressions/function/scope-name-var-open-non-strict.js b/test/language/expressions/function/scope-name-var-open-non-strict.js new file mode 100644 index 0000000000..4b85cf4ec8 --- /dev/null +++ b/test/language/expressions/function/scope-name-var-open-non-strict.js @@ -0,0 +1,50 @@ +// 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-function-definitions-runtime-semantics-evaluation +description: > + Creation of new variable environment for the BindingIdentifier + parameter +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, + funcEnv, strict). + [...] +flags: [noStrict] +---*/ + +var f = 'outside'; +var probeBefore = function() { return f; }; +var setBefore = function() { f = null; }; +var probeParams, setParams, probeBody, setBody; + +var func = function f( + _ = ( + probeParams = function() { return f; }, + setParams = function() { f = null; } + ) + ) { + probeBody = function() { return f; }; + setBody = function() { f = null; }; +}; + +func(); + +assert.sameValue(probeBefore(), 'outside'); +setBefore(); +assert.sameValue(probeBefore(), null); + +assert.sameValue(probeParams(), func, 'inner binding value (from parameters)'); +setParams(); +assert.sameValue( + probeParams(), func, 'inner binding is immutable (from parameters)' +); + +assert.sameValue(probeBody(), func, 'inner binding value (from body)'); +setBody(); +assert.sameValue(probeBody(), func, 'inner binding is immutable (from body)'); diff --git a/test/language/expressions/function/scope-name-var-open-strict.js b/test/language/expressions/function/scope-name-var-open-strict.js new file mode 100644 index 0000000000..0eeb49d3c1 --- /dev/null +++ b/test/language/expressions/function/scope-name-var-open-strict.js @@ -0,0 +1,54 @@ +// 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-function-definitions-runtime-semantics-evaluation +description: > + Creation of new variable environment for the BindingIdentifier + parameter +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, + funcEnv, strict). + [...] +flags: [onlyStrict] +---*/ + +var f = 'outside'; +var probeBefore = function() { return f; }; +var setBefore = function() { f = null; }; +var probeParams, setParams, probeBody, setBody; + +var func = function f( + _ = ( + probeParams = function() { return f; }, + setParams = function() { f = null; } + ) + ) { + probeBody = function() { return f; }; + setBody = function() { f = null; }; +}; + +func(); + +assert.sameValue(probeBefore(), 'outside'); +setBefore(); +assert.sameValue(probeBefore(), null); + +assert.sameValue(probeParams(), func, 'inner binding value (from parameters)'); +assert.throws( + TypeError, setParams, 'inner binding rejects modification (from parameters)' +); +assert.sameValue( + probeParams(), func, 'inner binding is immutable (from parameters)' +); + +assert.sameValue(probeBody(), func, 'inner binding value (from body)'); +assert.throws( + TypeError, setBody, 'inner binding rejects modification (from body)' +); +assert.sameValue(probeBody(), func, 'inner binding is immutable (from body)'); diff --git a/test/language/expressions/function/scope-param-elem-var-close.js b/test/language/expressions/function/scope-param-elem-var-close.js new file mode 100644 index 0000000000..4b7ffe8bc0 --- /dev/null +++ b/test/language/expressions/function/scope-param-elem-var-close.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +(function( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; +}()); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/function/scope-param-elem-var-open.js b/test/language/expressions/function/scope-param-elem-var-open.js new file mode 100644 index 0000000000..5306666a70 --- /dev/null +++ b/test/language/expressions/function/scope-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(function( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) { +}()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/function/scope-param-rest-elem-var-close.js b/test/language/expressions/function/scope-param-rest-elem-var-close.js new file mode 100644 index 0000000000..413efdba4d --- /dev/null +++ b/test/language/expressions/function/scope-param-rest-elem-var-close.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +(function( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } +}()); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/function/scope-param-rest-elem-var-open.js b/test/language/expressions/function/scope-param-rest-elem-var-open.js new file mode 100644 index 0000000000..dcac19412c --- /dev/null +++ b/test/language/expressions/function/scope-param-rest-elem-var-open.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(function( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) { +}()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/function/scope-paramsbody-var-close.js b/test/language/expressions/function/scope-paramsbody-var-close.js new file mode 100644 index 0000000000..147c303a17 --- /dev/null +++ b/test/language/expressions/function/scope-paramsbody-var-close.js @@ -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-functiondeclarationinstantiation +description: > + Removal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +// A parameter expression is necessary to trigger the creation of the scope +// under test. +(function(_ = null) { + var x = 'inside'; + probe = function() { return x; }; +}()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/function/scope-paramsbody-var-open.js b/test/language/expressions/function/scope-paramsbody-var-open.js new file mode 100644 index 0000000000..dc01b5e921 --- /dev/null +++ b/test/language/expressions/function/scope-paramsbody-var-open.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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +(function(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; +}()); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/generators/scope-body-lex-distinct.js b/test/language/expressions/generators/scope-body-lex-distinct.js new file mode 100644 index 0000000000..f793b54985 --- /dev/null +++ b/test/language/expressions/generators/scope-body-lex-distinct.js @@ -0,0 +1,54 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var g = function*() { + let x; + eval('var x;'); +}; +var iter = g(); + +assert.throws(SyntaxError, function() { + iter.next(); +}); diff --git a/test/language/expressions/generators/scope-name-var-close.js b/test/language/expressions/generators/scope-name-var-close.js new file mode 100644 index 0000000000..b163c1c013 --- /dev/null +++ b/test/language/expressions/generators/scope-name-var-close.js @@ -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-generator-function-definitions-runtime-semantics-evaluation +description: Removal of variable environment for the BindingIdentifier +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, + GeneratorBody, funcEnv, strict). + [...] +---*/ + +var probe; + +var func = function* g() { + probe = function() { return g; }; +}; +var g = 'outside'; + +func().next(); + +assert.sameValue(g, 'outside'); +assert.sameValue(probe(), func); diff --git a/test/language/expressions/generators/scope-name-var-open-non-strict.js b/test/language/expressions/generators/scope-name-var-open-non-strict.js new file mode 100644 index 0000000000..f15ae6c498 --- /dev/null +++ b/test/language/expressions/generators/scope-name-var-open-non-strict.js @@ -0,0 +1,50 @@ +// 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-generator-function-definitions-runtime-semantics-evaluation +description: > + Creation of new variable environment for the BindingIdentifier + parameter +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, + GeneratorBody, funcEnv, strict). + [...] +flags: [noStrict] +---*/ + +var g = 'outside'; +var probeBefore = function() { return g; }; +var setBefore = function() { g = null; }; +var probeParams, setParams, probeBody, setBody; + +var func = function* g( + _ = ( + probeParams = function() { return g; }, + setParams = function() { g = null; } + ) + ) { + probeBody = function() { return g; }; + setBody = function() { g = null; }; +}; + +func().next(); + +assert.sameValue(probeBefore(), 'outside'); +setBefore(); +assert.sameValue(probeBefore(), null); + +assert.sameValue(probeParams(), func, 'inner binding value (from parameters)'); +setParams(); +assert.sameValue( + probeParams(), func, 'inner binding is immutable (from parameters)' +); + +assert.sameValue(probeBody(), func, 'inner binding value (from body)'); +setBody(); +assert.sameValue(probeBody(), func, 'inner binding is immutable (from body)'); diff --git a/test/language/expressions/generators/scope-name-var-open-strict.js b/test/language/expressions/generators/scope-name-var-open-strict.js new file mode 100644 index 0000000000..2ba37c432a --- /dev/null +++ b/test/language/expressions/generators/scope-name-var-open-strict.js @@ -0,0 +1,54 @@ +// 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-generator-function-definitions-runtime-semantics-evaluation +description: > + Creation of new variable environment for the BindingIdentifier + parameter +info: | + [...] + 2. Let scope be the running execution context's LexicalEnvironment. + 3. Let funcEnv be NewDeclarativeEnvironment(scope). + 4. Let envRec be funcEnv's EnvironmentRecord. + 5. Let name be StringValue of BindingIdentifier. + 6. Perform envRec.CreateImmutableBinding(name, false). + 7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, + GeneratorBody, funcEnv, strict). + [...] +flags: [onlyStrict] +---*/ + +var g = 'outside'; +var probeBefore = function() { return g; }; +var setBefore = function() { g = null; }; +var probeParams, setParams, probeBody, setBody; + +var func = function* g( + _ = ( + probeParams = function() { return g; }, + setParams = function() { g = null; } + ) + ) { + probeBody = function() { return g; }; + setBody = function() { g = null; }; +}; + +func().next(); + +assert.sameValue(probeBefore(), 'outside'); +setBefore(); +assert.sameValue(probeBefore(), null); + +assert.sameValue(probeParams(), func, 'inner binding value (from parameters)'); +assert.throws( + TypeError, setParams, 'inner binding rejects modification (from parameters)' +); +assert.sameValue( + probeParams(), func, 'inner binding is immutable (from parameters)' +); + +assert.sameValue(probeBody(), func, 'inner binding value (from body)'); +assert.throws( + TypeError, setBody, 'inner binding rejects modification (from body)' +); +assert.sameValue(probeBody(), func, 'inner binding is immutable (from body)'); diff --git a/test/language/expressions/generators/scope-param-elem-var-close.js b/test/language/expressions/generators/scope-param-elem-var-close.js new file mode 100644 index 0000000000..a96e2a67d9 --- /dev/null +++ b/test/language/expressions/generators/scope-param-elem-var-close.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +(function*( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; +}()).next(); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/generators/scope-param-elem-var-open.js b/test/language/expressions/generators/scope-param-elem-var-open.js new file mode 100644 index 0000000000..3f2be0385d --- /dev/null +++ b/test/language/expressions/generators/scope-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(function*( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) { +}().next()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/generators/scope-param-rest-elem-var-close.js b/test/language/expressions/generators/scope-param-rest-elem-var-close.js new file mode 100644 index 0000000000..019ac5e9f8 --- /dev/null +++ b/test/language/expressions/generators/scope-param-rest-elem-var-close.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +(function*( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } +}().next()); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/generators/scope-param-rest-elem-var-open.js b/test/language/expressions/generators/scope-param-rest-elem-var-open.js new file mode 100644 index 0000000000..acc0a06e8e --- /dev/null +++ b/test/language/expressions/generators/scope-param-rest-elem-var-open.js @@ -0,0 +1,36 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +(function*( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) { +}().next()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/generators/scope-paramsbody-var-close.js b/test/language/expressions/generators/scope-paramsbody-var-close.js new file mode 100644 index 0000000000..520b549c9a --- /dev/null +++ b/test/language/expressions/generators/scope-paramsbody-var-close.js @@ -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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +// A parameter expression is necessary to trigger the creation of the scope +// under test. +(function*(_ = null) { + var x = 'inside'; + probe = function() { return x; }; +}().next()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/generators/scope-paramsbody-var-open.js b/test/language/expressions/generators/scope-paramsbody-var-open.js new file mode 100644 index 0000000000..d36a986079 --- /dev/null +++ b/test/language/expressions/generators/scope-paramsbody-var-open.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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +(function*(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; +}().next()); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/object/scope-gen-meth-body-lex-distinct.js b/test/language/expressions/object/scope-gen-meth-body-lex-distinct.js new file mode 100644 index 0000000000..6ddc563132 --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-body-lex-distinct.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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var o = { + *m() { + let x; + eval('var x;'); + } +}; +var iter = o.m(); + +assert.throws(SyntaxError, function() { + iter.next(); +}); diff --git a/test/language/expressions/object/scope-gen-meth-param-elem-var-close.js b/test/language/expressions/object/scope-gen-meth-param-elem-var-close.js new file mode 100644 index 0000000000..3785b8fd1c --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-param-elem-var-close.js @@ -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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +({ + *m( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; + } +}.m().next()); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/object/scope-gen-meth-param-elem-var-open.js b/test/language/expressions/object/scope-gen-meth-param-elem-var-open.js new file mode 100644 index 0000000000..8ff970f766 --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +({ + *m( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) {} +}.m().next()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-close.js b/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-close.js new file mode 100644 index 0000000000..b0d6ab104a --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-close.js @@ -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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +({ + *m( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } + } +}.m().next()); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-open.js b/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-open.js new file mode 100644 index 0000000000..dee21daa4c --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-param-rest-elem-var-open.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +({ + *m( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) {} +}.m().next()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/object/scope-gen-meth-paramsbody-var-close.js b/test/language/expressions/object/scope-gen-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..612ef84fdf --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-paramsbody-var-close.js @@ -0,0 +1,36 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +({ + // A parameter expression is necessary to trigger the creation of the scope + // under test. + *m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}.m().next()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/object/scope-gen-meth-paramsbody-var-open.js b/test/language/expressions/object/scope-gen-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..f3a1e4f9b0 --- /dev/null +++ b/test/language/expressions/object/scope-gen-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +({ + *m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}.m().next()); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/object/scope-getter-body-lex-distinc.js b/test/language/expressions/object/scope-getter-body-lex-distinc.js new file mode 100644 index 0000000000..7649bb6ad7 --- /dev/null +++ b/test/language/expressions/object/scope-getter-body-lex-distinc.js @@ -0,0 +1,55 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var o = { + get a() { + let x; + eval('var x;'); + } +}; + +assert.throws(SyntaxError, function() { + o.a; +}); diff --git a/test/language/expressions/object/scope-meth-body-lex-distinct.js b/test/language/expressions/object/scope-meth-body-lex-distinct.js new file mode 100644 index 0000000000..3c84edb0e6 --- /dev/null +++ b/test/language/expressions/object/scope-meth-body-lex-distinct.js @@ -0,0 +1,53 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var m = { + m() { + let x; + eval('var x;'); + } +}.m; + +assert.throws(SyntaxError, m); diff --git a/test/language/expressions/object/scope-meth-param-elem-var-close.js b/test/language/expressions/object/scope-meth-param-elem-var-close.js new file mode 100644 index 0000000000..66e9911e2c --- /dev/null +++ b/test/language/expressions/object/scope-meth-param-elem-var-close.js @@ -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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +({ + m( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; + } +}.m()); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/object/scope-meth-param-elem-var-open.js b/test/language/expressions/object/scope-meth-param-elem-var-open.js new file mode 100644 index 0000000000..ee8ecef830 --- /dev/null +++ b/test/language/expressions/object/scope-meth-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +({ + m( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) {} +}.m()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/object/scope-meth-param-rest-elem-var-close.js b/test/language/expressions/object/scope-meth-param-rest-elem-var-close.js new file mode 100644 index 0000000000..ea74544609 --- /dev/null +++ b/test/language/expressions/object/scope-meth-param-rest-elem-var-close.js @@ -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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +({ + m( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } + } +}.m()); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/expressions/object/scope-meth-param-rest-elem-var-open.js b/test/language/expressions/object/scope-meth-param-rest-elem-var-open.js new file mode 100644 index 0000000000..27ff352798 --- /dev/null +++ b/test/language/expressions/object/scope-meth-param-rest-elem-var-open.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +({ + m( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) {} +}.m()); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/expressions/object/scope-meth-paramsbody-var-close.js b/test/language/expressions/object/scope-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..f6958d0bed --- /dev/null +++ b/test/language/expressions/object/scope-meth-paramsbody-var-close.js @@ -0,0 +1,36 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +({ + // A parameter expression is necessary to trigger the creation of the scope + // under test. + m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}.m()); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/object/scope-meth-paramsbody-var-open.js b/test/language/expressions/object/scope-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..b8b2716e40 --- /dev/null +++ b/test/language/expressions/object/scope-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +({ + m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}.m()); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/expressions/object/scope-setter-body-lex-distinc.js b/test/language/expressions/object/scope-setter-body-lex-distinc.js new file mode 100644 index 0000000000..6e31ea3e61 --- /dev/null +++ b/test/language/expressions/object/scope-setter-body-lex-distinc.js @@ -0,0 +1,55 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +var o = { + set a(_) { + let x; + eval('var x;'); + } +}; + +assert.throws(SyntaxError, function() { + o.a = null; +}); diff --git a/test/language/expressions/object/scope-setter-paramsbody-var-close.js b/test/language/expressions/object/scope-setter-paramsbody-var-close.js new file mode 100644 index 0000000000..b9458d7142 --- /dev/null +++ b/test/language/expressions/object/scope-setter-paramsbody-var-close.js @@ -0,0 +1,36 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +({ + // A parameter expression is necessary to trigger the creation of the scope + // under test. + set a(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +}.a = null); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/expressions/object/scope-setter-paramsbody-var-open.js b/test/language/expressions/object/scope-setter-paramsbody-var-open.js new file mode 100644 index 0000000000..ce04f2ac35 --- /dev/null +++ b/test/language/expressions/object/scope-setter-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +({ + set a(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +}.a = undefined); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/block/scope-lex-close.js b/test/language/statements/block/scope-lex-close.js new file mode 100644 index 0000000000..b4b304b54e --- /dev/null +++ b/test/language/statements/block/scope-lex-close.js @@ -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-block-runtime-semantics-evaluation +description: Removal of lexical environment for BlockStatement +info: | + 1. Let oldEnv be the running execution context's LexicalEnvironment. + 2. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 3. Perform BlockDeclarationInstantiation(StatementList, blockEnv). + 4. Set the running execution context's LexicalEnvironment to blockEnv. + 5. Let blockValue be the result of evaluating StatementList. + 6. Set the running execution context's LexicalEnvironment to oldEnv. + 7. Return blockValue. +features: [let] +---*/ + +var probe; + +{ + let x = 'inside'; + probe = function() { return x; }; +} + +let x = 'outside'; + +assert.sameValue(x, 'outside'); +assert.sameValue(probe(), 'inside'); diff --git a/test/language/statements/block/scope-lex-open.js b/test/language/statements/block/scope-lex-open.js new file mode 100644 index 0000000000..5568c62729 --- /dev/null +++ b/test/language/statements/block/scope-lex-open.js @@ -0,0 +1,26 @@ +// 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-block-runtime-semantics-evaluation +description: Creation of new lexical environment for BlockStatement +info: | + 1. Let oldEnv be the running execution context's LexicalEnvironment. + 2. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 3. Perform BlockDeclarationInstantiation(StatementList, blockEnv). + 4. Set the running execution context's LexicalEnvironment to blockEnv. + 5. Let blockValue be the result of evaluating StatementList. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeBefore = function() { return x; }; +var probeInside; + +{ + let x = 'inside'; + probeInside = function() { return x; }; +} + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeInside(), 'inside'); diff --git a/test/language/statements/block/scope-var-none.js b/test/language/statements/block/scope-var-none.js new file mode 100644 index 0000000000..5d1c0862fb --- /dev/null +++ b/test/language/statements/block/scope-var-none.js @@ -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-block-runtime-semantics-evaluation +description: Retainment of existing variable environment for BlockStatement +info: | + 1. Let oldEnv be the running execution context's LexicalEnvironment. + 2. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 3. Perform BlockDeclarationInstantiation(StatementList, blockEnv). + 4. Set the running execution context's LexicalEnvironment to blockEnv. + 5. Let blockValue be the result of evaluating StatementList. + 6. Set the running execution context's LexicalEnvironment to oldEnv. + 7. Return blockValue. +---*/ + +var x = 'outside'; +var probeBefore = function() { return x; }; +var probeInside; + +{ + var x = 'inside'; + probeInside = function() { return x; }; +} + +assert.sameValue(probeBefore(), 'inside', 'reference preceeding statement'); +assert.sameValue(probeInside(), 'inside', 'reference within statement'); +assert.sameValue(x, 'inside', 'reference following statement'); diff --git a/test/language/statements/class/scope-gen-meth-paramsbody-var-close.js b/test/language/statements/class/scope-gen-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..e05a47fcd2 --- /dev/null +++ b/test/language/statements/class/scope-gen-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + *m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.prototype.m().next(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-gen-meth-paramsbody-var-open.js b/test/language/statements/class/scope-gen-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..ae60bf59ba --- /dev/null +++ b/test/language/statements/class/scope-gen-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + *m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.prototype.m().next(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/class/scope-meth-paramsbody-var-close.js b/test/language/statements/class/scope-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..ad48007664 --- /dev/null +++ b/test/language/statements/class/scope-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.prototype.m(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-meth-paramsbody-var-open.js b/test/language/statements/class/scope-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..827e3c6eb1 --- /dev/null +++ b/test/language/statements/class/scope-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.prototype.m(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/class/scope-name-lex-close.js b/test/language/statements/class/scope-name-lex-close.js new file mode 100644 index 0000000000..a6dedfd9ab --- /dev/null +++ b/test/language/statements/class/scope-name-lex-close.js @@ -0,0 +1,22 @@ +// 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-runtime-semantics-classdefinitionevaluation +description: Removal of lexical environment for class "name" +info: | + [...] + 22. Set the running execution context's LexicalEnvironment to lex. + [...] +---*/ + +class C { + method() { + return C; + } +} + +var cls = C; +assert.sameValue(typeof C, 'function'); +C = null; +assert.sameValue(C, null); +assert.sameValue(cls.prototype.method(), cls, 'from instance method'); diff --git a/test/language/statements/class/scope-name-lex-open-heritage.js b/test/language/statements/class/scope-name-lex-open-heritage.js new file mode 100644 index 0000000000..d844fd2c60 --- /dev/null +++ b/test/language/statements/class/scope-name-lex-open-heritage.js @@ -0,0 +1,46 @@ +// 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-runtime-semantics-classdefinitionevaluation +description: > + Creation of new lexical environment for the class "name" (with a heritage) +info: | + 1. Let lex be the LexicalEnvironment of the running execution context. + 2. Let classScope be NewDeclarativeEnvironment(lex). + 3. Let classScopeEnvRec be classScope's EnvironmentRecord. + 4. If className is not undefined, then + a. Perform classScopeEnvRec.CreateImmutableBinding(className, true). + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + a. Set the running execution context's LexicalEnvironment to classScope. + [...] +---*/ + +var setBefore = function() { C = null; }; +var probeBefore = function() { return C; }; +var probeHeritage, setHeritage; + +class C extends ( + probeHeritage = function() { return C; }, + setHeritage = function() { C = null; } + ) { + method() { + return C; + } +}; + +var cls = probeBefore(); +assert.sameValue(typeof cls, 'function'); +setBefore(); +assert.sameValue(probeBefore(), null); +assert.sameValue(probeHeritage(), cls, 'inner binding is independent'); +assert.throws( + TypeError, setHeritage, 'inner binding rejects modification' +); +assert.sameValue( + typeof probeHeritage(), 'function', 'inner binding is immutable' +); +assert.sameValue( + typeof cls.prototype.method(), 'function', 'from instance method' +); diff --git a/test/language/statements/class/scope-name-lex-open-no-heritage.js b/test/language/statements/class/scope-name-lex-open-no-heritage.js new file mode 100644 index 0000000000..87da14db01 --- /dev/null +++ b/test/language/statements/class/scope-name-lex-open-no-heritage.js @@ -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-runtime-semantics-classdefinitionevaluation +description: > + Creation of new lexical environment for the class "name" (without a + heritage) +info: | + 1. Let lex be the LexicalEnvironment of the running execution context. + 2. Let classScope be NewDeclarativeEnvironment(lex). + 3. Let classScopeEnvRec be classScope's EnvironmentRecord. + 4. If className is not undefined, then + a. Perform classScopeEnvRec.CreateImmutableBinding(className, true). + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + a. Set the running execution context's LexicalEnvironment to classScope. + [...] + 11. Set the running execution context's LexicalEnvironment to classScope. +---*/ + +var probeBefore = function() { return C; }; +var setBefore = function() { C = null; }; + +class C { + probe() { + return C; + } + modify() { + C = null; + } +}; + +var cls = probeBefore(); +assert.sameValue(typeof cls, 'function'); +setBefore(); +assert.sameValue(probeBefore(), null); + +assert.sameValue(cls.prototype.probe(), cls, 'inner binding value'); +assert.throws( + TypeError, cls.prototype.modify, 'inner binding rejects modification' +); +assert.sameValue( + typeof cls.prototype.probe(), 'function', 'inner binding is immutable' +); diff --git a/test/language/statements/class/scope-setter-paramsbody-var-close.js b/test/language/statements/class/scope-setter-paramsbody-var-close.js new file mode 100644 index 0000000000..b379cad2a0 --- /dev/null +++ b/test/language/statements/class/scope-setter-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + set a(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.prototype.a = null; + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-setter-paramsbody-var-open.js b/test/language/statements/class/scope-setter-paramsbody-var-open.js new file mode 100644 index 0000000000..1fca0b2b36 --- /dev/null +++ b/test/language/statements/class/scope-setter-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + set a(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.prototype.a = undefined; + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/class/scope-static-gen-meth-paramsbody-var-close.js b/test/language/statements/class/scope-static-gen-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..e830855773 --- /dev/null +++ b/test/language/statements/class/scope-static-gen-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static *m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.m().next(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-static-gen-meth-paramsbody-var-open.js b/test/language/statements/class/scope-static-gen-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..8ffba8b382 --- /dev/null +++ b/test/language/statements/class/scope-static-gen-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + static *m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.m().next(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/class/scope-static-meth-paramsbody-var-close.js b/test/language/statements/class/scope-static-meth-paramsbody-var-close.js new file mode 100644 index 0000000000..b26d03cb96 --- /dev/null +++ b/test/language/statements/class/scope-static-meth-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static m(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.m(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-static-meth-paramsbody-var-open.js b/test/language/statements/class/scope-static-meth-paramsbody-var-open.js new file mode 100644 index 0000000000..2d166ccba8 --- /dev/null +++ b/test/language/statements/class/scope-static-meth-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + static m(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.m(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/class/scope-static-setter-paramsbody-var-close.js b/test/language/statements/class/scope-static-setter-paramsbody-var-close.js new file mode 100644 index 0000000000..c3dd673911 --- /dev/null +++ b/test/language/statements/class/scope-static-setter-paramsbody-var-close.js @@ -0,0 +1,37 @@ +// 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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +class C { + // A parameter expression is necessary to trigger the creation of the scope + // under test. + static set a(_ = null) { + var x = 'inside'; + probe = function() { return x; }; + } +} +C.a = null; + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/class/scope-static-setter-paramsbody-var-open.js b/test/language/statements/class/scope-static-setter-paramsbody-var-open.js new file mode 100644 index 0000000000..ead07acabd --- /dev/null +++ b/test/language/statements/class/scope-static-setter-paramsbody-var-open.js @@ -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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +class C { + static set a(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; + } +} +C.a = undefined; + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/for-in/scope-body-lex-boundary.js b/test/language/statements/for-in/scope-body-lex-boundary.js new file mode 100644 index 0000000000..153442bd7d --- /dev/null +++ b/test/language/statements/for-in/scope-body-lex-boundary.js @@ -0,0 +1,50 @@ +// 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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for each evaluation of the statement + body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + i. Let result be the result of evaluating stmt. + j. Set the running execution context's LexicalEnvironment to oldEnv. + k. If LoopContinues(result, labelSet) is false, return ? + IteratorClose(iterator, UpdateEmpty(result, V)). + l. If result.[[Value]] is not empty, let V be result.[[Value]]. +features: [let] +---*/ + +let x = 'outside'; +var probeFirst, probeSecond; + +for (let x in { a: 0, b: 0 }) + if (!probeFirst) + probeFirst = function() { return x; }; + else + probeSecond = function() { return x; }; + + +// 13.7.5.15 EnumerateObjectProperties +// +// > [...] The mechanics and order of enumerating the properties is not +// > specified [...] +assert.notSameValue(probeFirst(), probeSecond()); +assert( + probeFirst() === 'a' || probeFirst() === 'b', + 'First binding is either "a" or "b"' +); +assert( + probeSecond() === 'a' || probeSecond() === 'b', + 'Second binding is either "a" or "b"' +); diff --git a/test/language/statements/for-in/scope-body-lex-close.js b/test/language/statements/for-in/scope-body-lex-close.js new file mode 100644 index 0000000000..609369bbea --- /dev/null +++ b/test/language/statements/for-in/scope-body-lex-close.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Removal of lexical environment for the initial evaluation of the statement + body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + i. Let result be the result of evaluating stmt. + j. Set the running execution context's LexicalEnvironment to oldEnv. + k. If LoopContinues(result, labelSet) is false, return ? + IteratorClose(iterator, UpdateEmpty(result, V)). + l. If result.[[Value]] is not empty, let V be result.[[Value]]. +features: [let] +---*/ + +let x = 'outside'; +var probeDecl, probeBody; + +for ( + let [x, _ = probeDecl = function() { return x; }] + in + { i: 0 } + ) + probeBody = function() { return x; }; + +assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'i', 'reference from statement body'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/for-in/scope-body-lex-open.js b/test/language/statements/for-in/scope-body-lex-open.js new file mode 100644 index 0000000000..8dfda9f595 --- /dev/null +++ b/test/language/statements/for-in/scope-body-lex-open.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for the initial evaluation of the + statement body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + d. If lhsKind is either assignment or varBinding, then + [...] + e. Else, + i. Assert: lhsKind is lexicalBinding. + ii. Assert: lhs is a ForDeclaration. + iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv). + iv. Perform BindingInstantiation for lhs passing iterationEnv as the + argument. + v. Set the running execution context's LexicalEnvironment to + iterationEnv. + [...] +features: [let] +---*/ + +var probeBefore = function() { return x; }; +let x = 'outside'; +var probeExpr, probeDecl, probeBody; + +for ( + let [x, _ = probeDecl = function() { return x; }] + in + { i: probeExpr = function() { typeof x; }} + ) + probeBody = function() { return x; }; + +assert.sameValue(probeBefore(), 'outside'); +assert.throws(ReferenceError, probeExpr); +assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'i', 'reference from statement body'); diff --git a/test/language/statements/for-in/scope-body-var-none.js b/test/language/statements/for-in/scope-body-var-none.js new file mode 100644 index 0000000000..23935da0b8 --- /dev/null +++ b/test/language/statements/for-in/scope-body-var-none.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: No variable environment is created for the statement body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + d. If lhsKind is either assignment or varBinding, then + [...] + e. Else, + i. Assert: lhsKind is lexicalBinding. + ii. Assert: lhs is a ForDeclaration. + iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv). + iv. Perform BindingInstantiation for lhs passing iterationEnv as the + argument. + v. Set the running execution context's LexicalEnvironment to + iterationEnv. + [...] +features: [let] +---*/ + +var probeBefore = function() { return x; }; +var probeExpr, probeDecl, probeBody; +var x = 1; + +for ( + let [_ = probeDecl = function() { return x; }] + in + { '': probeExpr = function() { return x; }} + ) + var x = 2, __ = probeBody = function() { return x; }; + + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression'); +assert.sameValue(probeDecl(), 2, 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 2, 'reference from statement body'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/for-in/scope-head-lex-close.js b/test/language/statements/for-in/scope-head-lex-close.js new file mode 100644 index 0000000000..a54e1a6f20 --- /dev/null +++ b/test/language/statements/for-in/scope-head-lex-close.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Removal of lexical environment to serve as a temporal dead zone for the + statement's AssignmentExpresson +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + 4. Set the running execution context's LexicalEnvironment to oldEnv. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeDecl, probeExpr, probeBody; + +for ( + let [x, _ = probeDecl = function() { return x; }] + in + { i: probeExpr = function() { typeof x; } } + ) + probeBody = function() { return x; }; + +assert.throws(ReferenceError, probeExpr); +assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'i', 'reference from statement body'); diff --git a/test/language/statements/for-in/scope-head-lex-open.js b/test/language/statements/for-in/scope-head-lex-open.js new file mode 100644 index 0000000000..db1cabaac1 --- /dev/null +++ b/test/language/statements/for-in/scope-head-lex-open.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment to serve as a temporal dead zone for + the statement's AssignmentExpresson +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeBefore = function() { return x; }; +var probeExpr; + +for (let x in { i: probeExpr = function() { typeof x; }}) ; + +assert.sameValue(probeBefore(), 'outside'); +assert.throws(ReferenceError, probeExpr); diff --git a/test/language/statements/for-in/scope-head-var-none.js b/test/language/statements/for-in/scope-head-var-none.js new file mode 100644 index 0000000000..d70d05076e --- /dev/null +++ b/test/language/statements/for-in/scope-head-var-none.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + No variable environment is created for the statement "head" +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + [...] +flags: [noStrict] +---*/ + +var probeBefore = function() { return x; }; +var x = 1; +var probeDecl, probeExpr, probeBody; + +for ( + let [_ = probeDecl = function() { return x; }] + in + { '': (eval('var x = 2;'), probeExpr = function() { return x; }) } + ) + probeBody = function() { return x; }; + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeDecl(), 2, 'reference from ForDeclaration'); +assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression'); +assert.sameValue(probeBody(), 2, 'reference from statement body'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/for-of/scope-body-lex-boundary.js b/test/language/statements/for-of/scope-body-lex-boundary.js new file mode 100644 index 0000000000..445b812ca9 --- /dev/null +++ b/test/language/statements/for-of/scope-body-lex-boundary.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for each evaluation of the statement + body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + i. Let result be the result of evaluating stmt. + j. Set the running execution context's LexicalEnvironment to oldEnv. + k. If LoopContinues(result, labelSet) is false, return ? + IteratorClose(iterator, UpdateEmpty(result, V)). + l. If result.[[Value]] is not empty, let V be result.[[Value]]. +features: [let] +---*/ + +let x = 'outside'; +var probeFirst, probeSecond; + +for (let x of ['first', 'second']) + if (!probeFirst) + probeFirst = function() { return x; }; + else + probeSecond = function() { return x; }; + +assert.sameValue(probeFirst(), 'first'); +assert.sameValue(probeSecond(), 'second'); diff --git a/test/language/statements/for-of/scope-body-lex-close.js b/test/language/statements/for-of/scope-body-lex-close.js new file mode 100644 index 0000000000..7e36cc9657 --- /dev/null +++ b/test/language/statements/for-of/scope-body-lex-close.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Removal of lexical environment for the initial evaluation of the statement + body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + i. Let result be the result of evaluating stmt. + j. Set the running execution context's LexicalEnvironment to oldEnv. + k. If LoopContinues(result, labelSet) is false, return ? + IteratorClose(iterator, UpdateEmpty(result, V)). + l. If result.[[Value]] is not empty, let V be result.[[Value]]. +features: [let] +---*/ + +let x = 'outside'; +var probeDecl, probeBody; + +for ( + let [x, _ = probeDecl = function() { return x; }] + of + [['inside']] + ) + probeBody = function() { return x; }; + +assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/for-of/scope-body-lex-open.js b/test/language/statements/for-of/scope-body-lex-open.js new file mode 100644 index 0000000000..bd0d0e938f --- /dev/null +++ b/test/language/statements/for-of/scope-body-lex-open.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for the initial evaluation of the + statement body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + d. If lhsKind is either assignment or varBinding, then + [...] + e. Else, + i. Assert: lhsKind is lexicalBinding. + ii. Assert: lhs is a ForDeclaration. + iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv). + iv. Perform BindingInstantiation for lhs passing iterationEnv as the + argument. + v. Set the running execution context's LexicalEnvironment to + iterationEnv. + [...] +features: [let] +---*/ + +var probeBefore = function() { return x; }; +let x = 'outside'; +var probeExpr, probeDecl, probeBody; + +for ( + let [x, _, __ = probeDecl = function() { return x; }] + of + [['inside', probeExpr = function() { typeof x; }]] + ) + probeBody = function() { return x; }; + +assert.sameValue(probeBefore(), 'outside'); +assert.throws(ReferenceError, probeExpr); +assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); diff --git a/test/language/statements/for-of/scope-body-var-none.js b/test/language/statements/for-of/scope-body-var-none.js new file mode 100644 index 0000000000..fe7ad9bf1b --- /dev/null +++ b/test/language/statements/for-of/scope-body-var-none.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: No variable environment is created for the statement body +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + [...] + 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, + lexicalBinding, labelSet). + + 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation + + [...] + 5. Repeat + [...] + d. If lhsKind is either assignment or varBinding, then + [...] + e. Else, + i. Assert: lhsKind is lexicalBinding. + ii. Assert: lhs is a ForDeclaration. + iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv). + iv. Perform BindingInstantiation for lhs passing iterationEnv as the + argument. + v. Set the running execution context's LexicalEnvironment to + iterationEnv. + [...] +features: [let] +---*/ + +var probeBefore = function() { return x; }; +var probeExpr, probeDecl, probeBody; +var x = 1; + +for ( + let [_, __ = probeDecl = function() { return x; }] + of + [[probeExpr = function() { return x; }]] + ) + var x = 2, ___ = probeBody = function() { return x; }; + + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression'); +assert.sameValue(probeDecl(), 2, 'reference from ForDelaration'); +assert.sameValue(probeBody(), 2, 'reference from statement body'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/for-of/scope-head-lex-close.js b/test/language/statements/for-of/scope-head-lex-close.js new file mode 100644 index 0000000000..808fceb47a --- /dev/null +++ b/test/language/statements/for-of/scope-head-lex-close.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Removal of lexical environment to serve as a temporal dead zone for the + statement's AssignmentExpresson +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + 4. Set the running execution context's LexicalEnvironment to oldEnv. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeDecl, probeExpr, probeBody; + +for ( + let [x, _ = probeDecl = function() { return x; }] + of + (probeExpr = function() { typeof x; }, [['inside']]) + ) + probeBody = function() { return x; }; + +assert.throws(ReferenceError, probeExpr); +assert.sameValue(probeDecl(), 'inside', 'reference from ForDeclaration'); +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); diff --git a/test/language/statements/for-of/scope-head-lex-open.js b/test/language/statements/for-of/scope-head-lex-open.js new file mode 100644 index 0000000000..4bcff42c1e --- /dev/null +++ b/test/language/statements/for-of/scope-head-lex-open.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment to serve as a temporal dead zone for + the statement's AssignmentExpresson +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeBefore = function() { return x; }; +var probeExpr; + +for (let x of (probeExpr = function() { typeof x; }, [])) ; + +assert.sameValue(probeBefore(), 'outside'); +assert.throws(ReferenceError, probeExpr); diff --git a/test/language/statements/for-of/scope-head-var-none.js b/test/language/statements/for-of/scope-head-var-none.js new file mode 100644 index 0000000000..d527736c74 --- /dev/null +++ b/test/language/statements/for-of/scope-head-var-none.js @@ -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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation +description: > + No variable environment is created for the statement "head" +info: | + IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement + + 1. Let keyResult be the result of performing ? + ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, + AssignmentExpression, iterate). + [...] + + 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation + + [...] + 2. If TDZnames is not an empty List, then + a. Assert: TDZnames has no duplicate entries. + b. Let TDZ be NewDeclarativeEnvironment(oldEnv). + c. Let TDZEnvRec be TDZ's EnvironmentRecord. + d. For each string name in TDZnames, do + i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). + e. Set the running execution context's LexicalEnvironment to TDZ. + 3. Let exprRef be the result of evaluating expr. + [...] +flags: [noStrict] +---*/ + +var probeBefore = function() { return x; }; +var x = 1; +var probeDecl, probeExpr, probeBody; + +for ( + let [_ = probeDecl = function() { return x; }] + of + [[eval('var x = 2;'), probeExpr = function() { return x; }]] + ) + probeBody = function() { return x; }; + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeDecl(), 2, 'reference from ForDeclaration'); +assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression'); +assert.sameValue(probeBody(), 2, 'reference from statement body'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/for/scope-body-lex-boundary.js b/test/language/statements/for/scope-body-lex-boundary.js new file mode 100644 index 0000000000..126d5f5973 --- /dev/null +++ b/test/language/statements/for/scope-body-lex-boundary.js @@ -0,0 +1,43 @@ +// 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-for-statement-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for each evaluation of the statement + body +info: | + [...] + 11. Let bodyResult be ForBodyEvaluation(the first Expression, the second + Expression, Statement, perIterationLets, labelSet). + [...] + + 13.7.4.8 Runtime Semantics: ForBodyEvaluation + + [...] + 3. Repeat + [...] + b. Let result be the result of evaluating stmt. + [...] + e. Perform ? CreatePerIterationEnvironment(perIterationBindings). + [...] + + 13.7.4.9 Runtime Semantics: CreatePerIterationEnvironment + + 1. If perIterationBindings has any elements, then + [...] + e. Let thisIterationEnv be NewDeclarativeEnvironment(outer). + f. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord. +features: [let] +---*/ + +var probeFirst; +var probeSecond = null; + +for (let x = 'first'; probeSecond === null; x = 'second') + if (!probeFirst) + probeFirst = function() { return x; }; + else + probeSecond = function() { return x; }; + +assert.sameValue(probeFirst(), 'first'); +assert.sameValue(probeSecond(), 'second'); diff --git a/test/language/statements/for/scope-body-lex-open.js b/test/language/statements/for/scope-body-lex-open.js new file mode 100644 index 0000000000..8efa583e88 --- /dev/null +++ b/test/language/statements/for/scope-body-lex-open.js @@ -0,0 +1,46 @@ +// 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-for-statement-runtime-semantics-labelledevaluation +description: > + Creation of new lexical environment for the initial evaluation of the + statement body +info: | + [...] + 11. Let bodyResult be ForBodyEvaluation(the first Expression, the second + Expression, Statement, perIterationLets, labelSet). + [...] + + 13.7.4.8 Runtime Semantics: ForBodyEvaluation + + [...] + 2. Perform ? CreatePerIterationEnvironment(perIterationBindings). + 3. Repeat + [...] + b. Let result be the result of evaluating stmt. + [...] + [...] + + 13.7.4.9 Runtime Semantics: CreatePerIterationEnvironment + + 1. If perIterationBindings has any elements, then + [...] + e. Let thisIterationEnv be NewDeclarativeEnvironment(outer). + f. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord. +features: [let] +---*/ + +var probeBefore, probeTest, probeIncr, probeBody; +var run = true; + +for ( + let x = 'outside', _ = probeBefore = function() { return x; }; + run && (x = 'inside', probeTest = function() { return x; }); + probeIncr = function() { return x; } + ) + probeBody = function() { return x; }, run = false; + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeTest(), 'inside', 'reference from "test" position'); +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); +assert.sameValue(probeIncr(), 'inside', 'reference from "increment" position'); diff --git a/test/language/statements/for/scope-body-var-none.js b/test/language/statements/for/scope-body-var-none.js new file mode 100644 index 0000000000..230c2abcf8 --- /dev/null +++ b/test/language/statements/for/scope-body-var-none.js @@ -0,0 +1,111 @@ +// 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-for-statement-runtime-semantics-labelledevaluation +description: > + No variable environment is created for each evaluation of the statement + body +info: | + [...] + 11. Let bodyResult be ForBodyEvaluation(the first Expression, the second + Expression, Statement, perIterationLets, labelSet). + [...] + + 13.7.4.8 Runtime Semantics: ForBodyEvaluation + + [...] + 2. Perform ? CreatePerIterationEnvironment(perIterationBindings). + 3. Repeat + [...] + b. Let result be the result of evaluating stmt. + [...] + e. Perform ? CreatePerIterationEnvironment(perIterationBindings). + [...] + + 13.7.4.9 Runtime Semantics: CreatePerIterationEnvironment + + 1. If perIterationBindings has any elements, then + [...] + e. Let thisIterationEnv be NewDeclarativeEnvironment(outer). + f. Let thisIterationEnvRec be thisIterationEnv's EnvironmentRecord. +flags: [noStrict] +---*/ + +var probeBefore = function() { return [x, y, z]; }; +var probeTest, probeIncr, probeBody; +var run = true; + +for ( + ; + run && (eval('var x = 1;'), probeTest = function() { return [x, y, z]; }); + eval('var y = 1;'), probeIncr = function() { return [x, y, z]; } + ) + var z = 1, _ = (probeBody = function() { return [x, y, z]; }), run = false; + +var x = 2; +var y = 2; +var z = 2; + +assert.sameValue( + probeBefore()[0], + 2, + 'reference preceeding statement (redeclared in "test" position)' +); +assert.sameValue( + probeBefore()[1], + 2, + 'reference preceeding statement (redeclared in statement body)' +); +assert.sameValue( + probeBefore()[2], + 2, + 'reference preceeding statement (redeclared in "increment" position)' +); + +assert.sameValue( + probeTest()[0], + 2, + 'reference from "test" position (redeclared in "test" position)' +); +assert.sameValue( + probeTest()[1], + 2, + 'reference from "test" position (redeclared in statement body)' +); +assert.sameValue( + probeTest()[2], + 2, + 'reference from "test" position (redeclared in "increment" position)' +); + +assert.sameValue( + probeBody()[0], + 2, + 'reference from statement body (redeclared in "test" position)' +); +assert.sameValue( + probeBody()[1], + 2, + 'reference from statement body (redeclared in statement body)' +); +assert.sameValue( + probeBody()[2], + 2, + 'reference from statement body (redeclared in "increment" position)' +); + +assert.sameValue( + probeIncr()[0], + 2, + 'reference from "increment" position (redeclared in "test" position)' +); +assert.sameValue( + probeIncr()[1], + 2, + 'reference from "increment" position (redeclared in statement body)' +); +assert.sameValue( + probeIncr()[2], + 2, + 'reference from "increment" position (redeclared in "increment" position)' +); diff --git a/test/language/statements/for/scope-head-lex-close.js b/test/language/statements/for/scope-head-lex-close.js new file mode 100644 index 0000000000..ac7eba5ee8 --- /dev/null +++ b/test/language/statements/for/scope-head-lex-close.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-for-statement-runtime-semantics-labelledevaluation +description: Removal of lexical environment for the statement "head" +info: | + [...] + 2. Let loopEnv be NewDeclarativeEnvironment(oldEnv). + 3. Let loopEnvRec be loopEnv's EnvironmentRecord. + 4. Let isConst be the result of performing IsConstantDeclaration of + LexicalDeclaration. + 5. Let boundNames be the BoundNames of LexicalDeclaration. + 6. For each element dn of boundNames do + a. If isConst is true, then + i. Perform ! loopEnvRec.CreateImmutableBinding(dn, true). + b. Else, + i. Perform ! loopEnvRec.CreateMutableBinding(dn, false). + 7. Set the running execution context's LexicalEnvironment to loopEnv. + [...] + 12. Set the running execution context's LexicalEnvironment to oldEnv. + 13. Return Completion(bodyResult). +features: [let] +---*/ + +let x = 'outside'; +var run = true; +var probeTest, probeIncr, probeBody; + +for ( + let x = 'inside'; + (probeTest = function() { return x; }) && run; + probeIncr = function() { return x; } + ) + probeBody = function() { return x; }, run = false; + +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); +assert.sameValue(probeIncr(), 'inside', 'reference from "increment" position'); +assert.sameValue(probeTest(), 'inside', 'reference from "test" position'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/for/scope-head-lex-open.js b/test/language/statements/for/scope-head-lex-open.js new file mode 100644 index 0000000000..6c8a7d1cbc --- /dev/null +++ b/test/language/statements/for/scope-head-lex-open.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-for-statement-runtime-semantics-labelledevaluation +description: Creation of new lexical environment for the statement "head" +info: | + [...] + 2. Let loopEnv be NewDeclarativeEnvironment(oldEnv). + 3. Let loopEnvRec be loopEnv's EnvironmentRecord. + 4. Let isConst be the result of performing IsConstantDeclaration of + LexicalDeclaration. + 5. Let boundNames be the BoundNames of LexicalDeclaration. + 6. For each element dn of boundNames do + a. If isConst is true, then + i. Perform ! loopEnvRec.CreateImmutableBinding(dn, true). + b. Else, + i. Perform ! loopEnvRec.CreateMutableBinding(dn, false). + 7. Set the running execution context's LexicalEnvironment to loopEnv. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeBefore = function() { return x; }; +var probeDecl, probeTest, probeIncr, probeBody; +var run = true; + +for ( + let x = 'inside', _ = probeDecl = function() { return x; }; + run && (probeTest = function() { return x; }); + probeIncr = function() { return x; } + ) + probeBody = function() { return x; }, run = false; + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeDecl(), 'inside', 'reference from LexicalDeclaration'); +assert.sameValue(probeTest(), 'inside', 'reference from "test" position'); +assert.sameValue(probeBody(), 'inside', 'reference from statement body'); +assert.sameValue(probeIncr(), 'inside', 'reference from "increment" position'); diff --git a/test/language/statements/for/scope-head-var-none.js b/test/language/statements/for/scope-head-var-none.js new file mode 100644 index 0000000000..301e5ee2f4 --- /dev/null +++ b/test/language/statements/for/scope-head-var-none.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-for-statement-runtime-semantics-labelledevaluation +description: No variable environment is created for the statement "head" +info: | + [...] + 2. Let loopEnv be NewDeclarativeEnvironment(oldEnv). + 3. Let loopEnvRec be loopEnv's EnvironmentRecord. + 4. Let isConst be the result of performing IsConstantDeclaration of + LexicalDeclaration. + 5. Let boundNames be the BoundNames of LexicalDeclaration. + 6. For each element dn of boundNames do + a. If isConst is true, then + i. Perform ! loopEnvRec.CreateImmutableBinding(dn, true). + b. Else, + i. Perform ! loopEnvRec.CreateMutableBinding(dn, false). + 7. Set the running execution context's LexicalEnvironment to loopEnv. + [...] + 12. Set the running execution context's LexicalEnvironment to oldEnv. + 13. Return Completion(bodyResult). +flags: [noStrict] +---*/ + +var probeBefore = function() { return x; }; +var probeTest, probeIncr, probeBody; +var run = true; + +for ( + var _ = eval('var x = 1;'); + run && (probeTest = function() { return x; }); + probeIncr = function() { return x; } + ) + probeBody = function() { return x; }, run = false; + +var x = 2; + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeTest(), 2, 'reference from "test" position'); +assert.sameValue(probeBody(), 2, 'reference from statement body'); +assert.sameValue(probeIncr(), 2, 'reference from "increment" position'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/function/scope-body-lex-distinct.js b/test/language/statements/function/scope-body-lex-distinct.js new file mode 100644 index 0000000000..55e1a5a558 --- /dev/null +++ b/test/language/statements/function/scope-body-lex-distinct.js @@ -0,0 +1,53 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +function f() { + let x; + eval('var x;'); +} + +assert.throws(SyntaxError, function() { + f(); +}); diff --git a/test/language/statements/function/scope-param-elem-var-close.js b/test/language/statements/function/scope-param-elem-var-close.js new file mode 100644 index 0000000000..f7f0a3a6a1 --- /dev/null +++ b/test/language/statements/function/scope-param-elem-var-close.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +function f( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; +} +f(); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/statements/function/scope-param-elem-var-open.js b/test/language/statements/function/scope-param-elem-var-open.js new file mode 100644 index 0000000000..18e2442245 --- /dev/null +++ b/test/language/statements/function/scope-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +function f( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) { +} +f(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/statements/function/scope-param-rest-elem-var-close.js b/test/language/statements/function/scope-param-rest-elem-var-close.js new file mode 100644 index 0000000000..1c32484046 --- /dev/null +++ b/test/language/statements/function/scope-param-rest-elem-var-close.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +function f( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } +} +f(); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/statements/function/scope-param-rest-elem-var-open.js b/test/language/statements/function/scope-param-rest-elem-var-open.js new file mode 100644 index 0000000000..632fd2f3c2 --- /dev/null +++ b/test/language/statements/function/scope-param-rest-elem-var-open.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +function f( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) { +} +f(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/statements/function/scope-paramsbody-var-close.js b/test/language/statements/function/scope-paramsbody-var-close.js new file mode 100644 index 0000000000..f99b49bf77 --- /dev/null +++ b/test/language/statements/function/scope-paramsbody-var-close.js @@ -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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +// A parameter expression is necessary to trigger the creation of the scope +// under test. +function f(_ = null) { + var x = 'inside'; + probe = function() { return x; }; +} +f(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/function/scope-paramsbody-var-open.js b/test/language/statements/function/scope-paramsbody-var-open.js new file mode 100644 index 0000000000..b460625d9b --- /dev/null +++ b/test/language/statements/function/scope-paramsbody-var-open.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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +function f(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; +} +f(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/generators/scope-body-lex-distinct.js b/test/language/statements/generators/scope-body-lex-distinct.js new file mode 100644 index 0000000000..9506c1b85d --- /dev/null +++ b/test/language/statements/generators/scope-body-lex-distinct.js @@ -0,0 +1,54 @@ +// 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-functiondeclarationinstantiation +description: > + Creation of new lexical environment (distinct from the variable + environment) for the function body outside of strict mode +info: | + [...] + 29. If strict is false, then + a. Let lexEnv be NewDeclarativeEnvironment(varEnv). + b. NOTE: Non-strict functions use a separate lexical Environment Record + for top-level lexical declarations so that a direct eval can + determine whether any var scoped declarations introduced by the eval + code conflict with pre-existing top-level lexically scoped + declarations. This is not needed for strict functions because a + strict direct eval always places all declarations into a new + Environment Record. + [...] + + 18.2.1.3 Runtime Semantics: EvalDeclarationInstantiation + + [...] + 5. If strict is false, then + [...] + b. Let thisLex be lexEnv. + c. Assert: The following loop will terminate. + 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. + ii. NOTE: Annex B.3.5 defines alternate semantics for the + above step. + 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] +---*/ + +function* g() { + let x; + eval('var x;'); +} +var iter = g(); + +assert.throws(SyntaxError, function() { + iter.next(); +}); diff --git a/test/language/statements/generators/scope-param-elem-var-close.js b/test/language/statements/generators/scope-param-elem-var-close.js new file mode 100644 index 0000000000..b3185aceff --- /dev/null +++ b/test/language/statements/generators/scope-param-elem-var-close.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for each BindingElement formal parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2, probeBody; + +function* g( + _ = (eval('var x = "inside";'), probe1 = function() { return x; }), + __ = probe2 = function() { return x; } + ) { + probeBody = function() { return x; }; +} +g().next(); + +assert.sameValue(probe1(), 'inside'); +assert.sameValue(probe2(), 'outside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/statements/generators/scope-param-elem-var-open.js b/test/language/statements/generators/scope-param-elem-var-open.js new file mode 100644 index 0000000000..461be1c9ad --- /dev/null +++ b/test/language/statements/generators/scope-param-elem-var-open.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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for each BindingElement formal + parameter +info: | + [...] + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +function* g( + _ = probe1 = function() { return x; }, + __ = (eval('var x = "inside";'), probe2 = function() { return x; }) + ) { +} +g().next(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/statements/generators/scope-param-rest-elem-var-close.js b/test/language/statements/generators/scope-param-rest-elem-var-close.js new file mode 100644 index 0000000000..ee534ec079 --- /dev/null +++ b/test/language/statements/generators/scope-param-rest-elem-var-close.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Removal of variable environment for the BindingRestElement formal parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the + arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probeParam, probeBody; + +function* g( + ...[_ = (eval('var x = "inside";'), probeParam = function() { return x; })] + ) { + probeBody = function() { return x; } +} +g().next(); + +assert.sameValue(probeParam(), 'inside'); +assert.sameValue(probeBody(), 'outside'); diff --git a/test/language/statements/generators/scope-param-rest-elem-var-open.js b/test/language/statements/generators/scope-param-rest-elem-var-open.js new file mode 100644 index 0000000000..73d6b348d4 --- /dev/null +++ b/test/language/statements/generators/scope-param-rest-elem-var-open.js @@ -0,0 +1,37 @@ +// 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-function-definitions-runtime-semantics-iteratorbindinginitialization +description: > + Creation of new variable environment for the BindingRestElement formal + parameter +info: | + [...] + 2. Let currentContext be the running execution context. + 3. Let originalEnv be the VariableEnvironment of currentContext. + 4. Assert: The VariableEnvironment and LexicalEnvironment of currentContext + are the same. + 5. Assert: environment and originalEnv are the same. + 6. Let paramVarEnv be NewDeclarativeEnvironment(originalEnv). + 7. Set the VariableEnvironment of currentContext to paramVarEnv. + 8. Set the LexicalEnvironment of currentContext to paramVarEnv. + 9. Let result be the result of performing IteratorBindingInitialization for + BindingRestElement using iteratorRecord and environment as the arguments. + 10. Set the VariableEnvironment of currentContext to originalEnv. + 11. Set the LexicalEnvironment of currentContext to originalEnv. + [...] +flags: [noStrict] +---*/ + +var x = 'outside'; +var probe1, probe2; + +function* g( + _ = probe1 = function() { return x; }, + ...[__ = (eval('var x = "inside";'), probe2 = function() { return x; })] + ) { +} +g().next(); + +assert.sameValue(probe1(), 'outside'); +assert.sameValue(probe2(), 'inside'); diff --git a/test/language/statements/generators/scope-paramsbody-var-close.js b/test/language/statements/generators/scope-paramsbody-var-close.js new file mode 100644 index 0000000000..22fd3651e8 --- /dev/null +++ b/test/language/statements/generators/scope-paramsbody-var-close.js @@ -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-functiondeclarationinstantiation +description: > + Disposal of variable environment for the function body +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var probe; + +// A parameter expression is necessary to trigger the creation of the scope +// under test. +function* g(_ = null) { + var x = 'inside'; + probe = function() { return x; }; +} +g().next(); + +var x = 'outside'; + +assert.sameValue(probe(), 'inside'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/generators/scope-paramsbody-var-open.js b/test/language/statements/generators/scope-paramsbody-var-open.js new file mode 100644 index 0000000000..e84dcca348 --- /dev/null +++ b/test/language/statements/generators/scope-paramsbody-var-open.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-functiondeclarationinstantiation +description: > + Creation of new variable environment for the function body (as disinct from + that for the function's parameters) +info: | + [...] + 26. If hasParameterExpressions is false, then + [...] + 27. Else, + a. NOTE A separate Environment Record is needed to ensure that closures + created by expressions in the formal parameter list do not have + visibility of declarations in the function body. + b. Let varEnv be NewDeclarativeEnvironment(env). + c. Let varEnvRec be varEnv's EnvironmentRecord. + d. Set the VariableEnvironment of calleeContext to varEnv. + e. Let instantiatedVarNames be a new empty List. + [...] +---*/ + +var x = 'outside'; +var probeParams, probeBody; + +function* g(_ = probeParams = function() { return x; }) { + var x = 'inside'; + probeBody = function() { return x; }; +} +g().next(); + +assert.sameValue(probeParams(), 'outside'); +assert.sameValue(probeBody(), 'inside'); diff --git a/test/language/statements/switch/scope-lex-close-case.js b/test/language/statements/switch/scope-lex-close-case.js new file mode 100644 index 0000000000..767f716035 --- /dev/null +++ b/test/language/statements/switch/scope-lex-close-case.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-switch-statement-runtime-semantics-evaluation +description: Removal of lexical environment (from `case` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probe1, probe2; + +switch (null) { + case null: + let x = 'inside'; + probe1 = function() { return x; }; + case null: + probe2 = function() { return x; }; +} + +assert.sameValue(probe1(), 'inside', 'from first `case` clause'); +assert.sameValue(probe2(), 'inside', 'from second `case` clause'); +assert.sameValue(x, 'outside'); diff --git a/test/language/statements/switch/scope-lex-close-dflt.js b/test/language/statements/switch/scope-lex-close-dflt.js new file mode 100644 index 0000000000..fb6aa338bd --- /dev/null +++ b/test/language/statements/switch/scope-lex-close-dflt.js @@ -0,0 +1,46 @@ +// 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-switch-statement-runtime-semantics-evaluation +description: Removal of lexical environment (from `default` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeDefault, probeDefaultBeforeCase, probeCase; + +switch (null) { + default: + let x = 'inside'; + probeDefault = function() { return x; }; +} + +assert.sameValue(probeDefault(), 'inside', 'from lone `default` clause`'); +assert.sameValue(x, 'outside'); + +switch (null) { + default: + let x = 'inside'; + probeDefaultBeforeCase = function() { return x; }; + case 0: + probeCase = function() { return x; }; +} + +assert.sameValue( + probeDefaultBeforeCase(), + 'inside', + 'from `default` clause preceeding `case` clause' +); +assert.sameValue( + probeCase(), 'inside', 'from `case` clause following `default` clause' +); diff --git a/test/language/statements/switch/scope-lex-open-case.js b/test/language/statements/switch/scope-lex-open-case.js new file mode 100644 index 0000000000..bb0edd8889 --- /dev/null +++ b/test/language/statements/switch/scope-lex-open-case.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-switch-statement-runtime-semantics-evaluation +description: Creation of new lexical environment (into `case` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeExpr, probeSelector, probeStmt; + +switch (probeExpr = function() { return x; }, null) { + case probeSelector = function() { return x; }, null: + probeStmt = function() { return x; }; + let x = 'inside'; +} + +assert.sameValue(probeExpr(), 'outside'); +assert.sameValue( + probeSelector(), 'inside', 'reference from "selector" Expression' +); +assert.sameValue(probeStmt(), 'inside', 'reference from Statement position'); diff --git a/test/language/statements/switch/scope-lex-open-dflt.js b/test/language/statements/switch/scope-lex-open-dflt.js new file mode 100644 index 0000000000..7df609c6d2 --- /dev/null +++ b/test/language/statements/switch/scope-lex-open-dflt.js @@ -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-switch-statement-runtime-semantics-evaluation +description: Creation of new lexical environment (into `default` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +features: [let] +---*/ + +let x = 'outside'; +var probeExpr, probeStmt; + +switch (probeExpr = function() { return x; }) { + default: + probeStmt = function() { return x; }; + let x = 'inside'; +} + +assert.sameValue(probeExpr(), 'outside'); +assert.sameValue(probeStmt(), 'inside'); diff --git a/test/language/statements/switch/scope-var-none-case.js b/test/language/statements/switch/scope-var-none-case.js new file mode 100644 index 0000000000..0f6019faaa --- /dev/null +++ b/test/language/statements/switch/scope-var-none-case.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-switch-statement-runtime-semantics-evaluation +description: Retainment of existing variable environment (`case` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +flags: [noStrict] +---*/ + +var probeExpr, probeSelector, probeStmt; +var probeBefore = function() { return x; }; + +switch (eval('var x = 1;'), probeExpr = function() { return x; }, null) { + case eval('var x = 2;'), probeSelector = function() { return x; }, null: + probeStmt = function() { return x; }; + var x = 3; +} + +assert.sameValue(probeBefore(), 3, 'reference preceeding statement'); +assert.sameValue(probeExpr(), 3, 'reference from first Expression'); +assert.sameValue(probeSelector(), 3, 'reference from "selector" Expression'); +assert.sameValue(probeStmt(), 3, 'reference from Statement position'); +assert.sameValue(x, 3, 'reference following statement'); diff --git a/test/language/statements/switch/scope-var-none-dflt.js b/test/language/statements/switch/scope-var-none-dflt.js new file mode 100644 index 0000000000..229084095c --- /dev/null +++ b/test/language/statements/switch/scope-var-none-dflt.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-switch-statement-runtime-semantics-evaluation +description: Retainment of existing variable environment (`default` clause) +info: | + 1. Let exprRef be the result of evaluating Expression. + 2. Let switchValue be ? GetValue(exprRef). + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let blockEnv be NewDeclarativeEnvironment(oldEnv). + 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv). + 6. Set the running execution context's LexicalEnvironment to blockEnv. + 7. Let R be the result of performing CaseBlockEvaluation of CaseBlock with + argument switchValue. + [...] +flags: [noStrict] +---*/ + +var probeExpr, probeStmt; +var probeBefore = function() { return x; }; + +switch (eval('var x = 1;'), probeExpr = function() { return x; }) { + default: + probeStmt = function() { return x; }; + var x = 2; +} + +assert.sameValue(probeBefore(), 2, 'reference preceeding statment'); +assert.sameValue(probeExpr(), 2, 'reference from Expression position'); +assert.sameValue(probeStmt(), 2, 'reference from Statement position'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/try/scope-catch-block-lex-close.js b/test/language/statements/try/scope-catch-block-lex-close.js new file mode 100644 index 0000000000..458831d97f --- /dev/null +++ b/test/language/statements/try/scope-catch-block-lex-close.js @@ -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-runtime-semantics-catchclauseevaluation +description: Removal of lexical environment for `catch` block +info: | + [...] + 8. Let B be the result of evaluating Block. + [...] +features: [let] +---*/ + +var probe, x; + +try { + throw null; +} catch (_) { + let x = 'inside'; + probe = function() { return x; }; +} +x = 'outside'; + +assert.sameValue(x, 'outside'); +assert.sameValue(probe(), 'inside'); diff --git a/test/language/statements/try/scope-catch-block-lex-open.js b/test/language/statements/try/scope-catch-block-lex-open.js new file mode 100644 index 0000000000..10b7ddf994 --- /dev/null +++ b/test/language/statements/try/scope-catch-block-lex-open.js @@ -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-runtime-semantics-catchclauseevaluation +description: Creation of new lexical environment for `catch` block +info: | + [...] + 8. Let B be the result of evaluating Block. + [...] +features: [let] +---*/ + +var probeParam, probeBlock; +let x = 'outside'; + +try { + throw []; +} catch ([_ = probeParam = function() { return x; }]) { + probeBlock = function() { return x; }; + let x = 'inside'; +} + +assert.sameValue(probeParam(), 'outside'); +assert.sameValue(probeBlock(), 'inside'); diff --git a/test/language/statements/try/scope-catch-block-var-none.js b/test/language/statements/try/scope-catch-block-var-none.js new file mode 100644 index 0000000000..de10923b93 --- /dev/null +++ b/test/language/statements/try/scope-catch-block-var-none.js @@ -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. +/*--- +esid: sec-runtime-semantics-catchclauseevaluation +description: Retainment of existing variable environment for `catch` block +info: | + [...] + 8. Let B be the result of evaluating Block. + [...] +---*/ + +var x = 1; +var probeBefore = function() { return x; }; +var probeInside; + +try { + throw null; +} catch (_) { + var x = 2; + probeInside = function() { return x; }; +} + +assert.sameValue(probeBefore(), 2, 'reference preceeding statement'); +assert.sameValue(probeInside(), 2, 'reference within statement'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/try/scope-catch-param-lex-close.js b/test/language/statements/try/scope-catch-param-lex-close.js new file mode 100644 index 0000000000..682b5a8c10 --- /dev/null +++ b/test/language/statements/try/scope-catch-param-lex-close.js @@ -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-runtime-semantics-catchclauseevaluation +description: Removal of lexical environment for `catch` parameter +---*/ + +var probe, x; + +try { + throw 'inside'; +} catch (x) { + probe = function() { return x; }; +} +x = 'outside'; + +assert.sameValue(x, 'outside'); +assert.sameValue(probe(), 'inside'); diff --git a/test/language/statements/try/scope-catch-param-lex-open.js b/test/language/statements/try/scope-catch-param-lex-open.js new file mode 100644 index 0000000000..5ade7b0210 --- /dev/null +++ b/test/language/statements/try/scope-catch-param-lex-open.js @@ -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-runtime-semantics-catchclauseevaluation +description: Creation of new lexical environment for `catch` parameter +---*/ + +var probeBefore = function() { return x; }; +var probeTry, probeParam; +var x = 'outside'; + +try { + probeTry = function() { return x; }; + + throw ['inside']; +} catch ([x, _ = probeParam = function() { return x; }]) {} + +assert.sameValue(probeBefore(), 'outside'); +assert.sameValue(probeTry(), 'outside'); +assert.sameValue(probeParam(), 'inside'); diff --git a/test/language/statements/try/scope-catch-param-var-none.js b/test/language/statements/try/scope-catch-param-var-none.js new file mode 100644 index 0000000000..910eceea1a --- /dev/null +++ b/test/language/statements/try/scope-catch-param-var-none.js @@ -0,0 +1,26 @@ +// 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-runtime-semantics-catchclauseevaluation +description: Retainment of existing variable environment for `catch` parameter +flags: [noStrict] +---*/ + +var x = 1; +var probeBefore = function() { return x; }; +var probeTry, probeParam, probeBlock; + +try { + var x = 2; + probeTry = function() { return x; }; + throw []; +} catch ([_ = (eval('var x = 3;'), probeParam = function() { return x; })]) { + var x = 4; + probeBlock = function() { return x; }; +} + +assert.sameValue(probeBefore(), 4, 'reference preceeding statement'); +assert.sameValue(probeTry(), 4, 'reference from `try` block'); +assert.sameValue(probeParam(), 4, 'reference within CatchParameter'); +assert.sameValue(probeBlock(), 4, 'reference from `catch` block'); +assert.sameValue(x, 4, 'reference following statement'); diff --git a/test/language/statements/with/scope-var-close.js b/test/language/statements/with/scope-var-close.js new file mode 100644 index 0000000000..be804d7300 --- /dev/null +++ b/test/language/statements/with/scope-var-close.js @@ -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. +/*--- +esid: sec-with-statement-runtime-semantics-evaluation +es6id: 13.11.7 +description: Removal of variable environment +info: | + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let newEnv be NewObjectEnvironment(obj, oldEnv). + 5. Set the withEnvironment flag of newEnv's EnvironmentRecord to true. + 6. Set the running execution context's LexicalEnvironment to newEnv. + 7. Let C be the result of evaluating Statement. + 8. Set the running execution context's LexicalEnvironment to oldEnv. +flags: [noStrict] +---*/ + +var probeBody; + +with ({ x: 0 }) + var x = 1, _ = probeBody = function() { return x; }; + +var x = 2; + +assert.sameValue(probeBody(), 1, 'reference from statement body'); +assert.sameValue(x, 2, 'reference following statement'); diff --git a/test/language/statements/with/scope-var-open.js b/test/language/statements/with/scope-var-open.js new file mode 100644 index 0000000000..00dd5b4d55 --- /dev/null +++ b/test/language/statements/with/scope-var-open.js @@ -0,0 +1,26 @@ +// 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-with-statement-runtime-semantics-evaluation +es6id: 13.11.7 +description: Creation of new variable environment +info: | + 3. Let oldEnv be the running execution context's LexicalEnvironment. + 4. Let newEnv be NewObjectEnvironment(obj, oldEnv). + 5. Set the withEnvironment flag of newEnv's EnvironmentRecord to true. + 6. Set the running execution context's LexicalEnvironment to newEnv. + 7. Let C be the result of evaluating Statement. +flags: [noStrict] +---*/ + +var x = 0; +var objectRecord = { x: 2 }; +var probeBefore = function() { return x; }; +var probeExpr, probeBody; + +with (eval('var x = 1;'), probeExpr = function() { return x; }, objectRecord) + var x = 3, _ = probeBody = function() { return x; }; + +assert.sameValue(probeBefore(), 1, 'reference preceeding statement'); +assert.sameValue(probeExpr(), 1, 'reference from expression'); +assert.sameValue(probeBody(), 3, 'reference from statement body');