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 0000000000000000000000000000000000000000..9416b7fdc34b49e8eb70ca837c4533a9a1012097 --- /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 0000000000000000000000000000000000000000..bcb987ebb98dd6a66f7aecb0d6028df74a07538b --- /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 0000000000000000000000000000000000000000..7f60a0610231c0ea017a4e07fb25d1d80852265f --- /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 0000000000000000000000000000000000000000..976565a989399477709701eda55b055cd9fd091e --- /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 0000000000000000000000000000000000000000..b7a88bc0500e983cd8090ad8da65b2d0597c7044 --- /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 0000000000000000000000000000000000000000..a0472fc272bdd2a429173f8c15ea44112c06ebdf --- /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 0000000000000000000000000000000000000000..c0bc7669fa829266a9d215755314bba3e54b4209 --- /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 0000000000000000000000000000000000000000..a9f048cbc7d6cba11b6dd64a2de81742e795e14d --- /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 0000000000000000000000000000000000000000..9f1e2cc1af46a0efcee7827d1060b2520e9aa127 --- /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 0000000000000000000000000000000000000000..5a76a49ea5a75bf4e01d79201fc72942484a0ba1 --- /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 0000000000000000000000000000000000000000..a50cc1e2c9a084ee23ccc25bb620bfc7b7e7ed72 --- /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 0000000000000000000000000000000000000000..d0f4280f8f81b7ebbe24eb065b72fc1368031190 --- /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 0000000000000000000000000000000000000000..1b09a356e984105a65790e09042d3beae7e32e81 --- /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 0000000000000000000000000000000000000000..b3b9a67fa762f5aa37342c7ec558ffffeee9997f --- /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 0000000000000000000000000000000000000000..843a8b6d3ee5f28e5aca910bcfa3fd4e8de7553f --- /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 0000000000000000000000000000000000000000..4776a1e314265c8d7623b338427d73ed9b243a44 --- /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 0000000000000000000000000000000000000000..e7d16fb4980a0065663a51b169a6677c34d1c60e --- /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 0000000000000000000000000000000000000000..2717b51b583f9022f82025638491d1f3b1c6867e --- /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 0000000000000000000000000000000000000000..9d025c223035aae13d933266f0e9a4769449835e --- /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 0000000000000000000000000000000000000000..46db7ba16b84d7766d1cb314fd8e24b660798ddb --- /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 0000000000000000000000000000000000000000..26ef25edc823ddc76b9cf2c10c67bacf547db1fb --- /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 0000000000000000000000000000000000000000..17167c3ce4c06ce139a00b58792f6cd3d3b9c617 --- /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 0000000000000000000000000000000000000000..6b55004eac08e7867dadc2381513986e68978af9 --- /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 0000000000000000000000000000000000000000..44dfe39d761de1aa4e72d4ef9631dc9f60c3df38 --- /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 0000000000000000000000000000000000000000..1ded6d1b4ed0d9b8c8b2b40ef2d9d7529974b644 --- /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 0000000000000000000000000000000000000000..5f01fdbe5dc1b3e1ce2d7f1008c49518465d18ce --- /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 0000000000000000000000000000000000000000..3fbaa973c9a4e594cbd83177b631ec5f7208bb82 --- /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 0000000000000000000000000000000000000000..c119ca277100ac2f54b1bc193ecf04370d5a93e9 --- /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 0000000000000000000000000000000000000000..4b85cf4ec86fea6c18975d6b9c15ae19ab0dbc9a --- /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 0000000000000000000000000000000000000000..0eeb49d3c1ff9a2888f9dd32a0281beec197c806 --- /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 0000000000000000000000000000000000000000..4b7ffe8bc06e77343b694dc0f469d9deed5b98ba --- /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 0000000000000000000000000000000000000000..5306666a70bd2fe13316651f1f8e62c718954cc2 --- /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 0000000000000000000000000000000000000000..413efdba4de98396be48c90cc72b737a8ef7ff96 --- /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 0000000000000000000000000000000000000000..dcac19412cdee1a7345b9113e1b18e316f637019 --- /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 0000000000000000000000000000000000000000..147c303a17344d44d397b8d4469e653d979919ce --- /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 0000000000000000000000000000000000000000..dc01b5e921dcc2117861509731eba073fdbc9a54 --- /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 0000000000000000000000000000000000000000..f793b54985fd83b57d902fac062c5a2560893117 --- /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 0000000000000000000000000000000000000000..b163c1c013acc70527d35bc91d4eeeeffc10cd72 --- /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 0000000000000000000000000000000000000000..f15ae6c49872eb66667c2140066e07c784dbfa3a --- /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 0000000000000000000000000000000000000000..2ba37c432ad023030b4e22c6572c46b46005e488 --- /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 0000000000000000000000000000000000000000..a96e2a67d926ce736a2c3de57ee637da7951d6b1 --- /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 0000000000000000000000000000000000000000..3f2be0385d9aefc989700e0e2536940dacea091f --- /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 0000000000000000000000000000000000000000..019ac5e9f8f0ff2b6503b5e5a77461b18512fd62 --- /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 0000000000000000000000000000000000000000..acc0a06e8ef96fe8ea0055417a76aca4c37560c4 --- /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 0000000000000000000000000000000000000000..520b549c9ae89523089070f3ffd5ebd899a7a4b1 --- /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 0000000000000000000000000000000000000000..d36a986079b18702c83a72286ee120b633667de3 --- /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 0000000000000000000000000000000000000000..6ddc563132e02ce20b6e078341adc9a1ce3c15a9 --- /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 0000000000000000000000000000000000000000..3785b8fd1cf1ec347aa377e83482485300fc24c5 --- /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 0000000000000000000000000000000000000000..8ff970f766255d68bbbf484446faaaaff4409777 --- /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 0000000000000000000000000000000000000000..b0d6ab104a60cde0d752c6a5f1f1601f96cc87a3 --- /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 0000000000000000000000000000000000000000..dee21daa4ce35af76991dcd7bd57c6040147e7ba --- /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 0000000000000000000000000000000000000000..612ef84fdf61073b0a0a130c47e3a4458692d616 --- /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 0000000000000000000000000000000000000000..f3a1e4f9b07d46f98d72832fa50a30bb92f2447f --- /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 0000000000000000000000000000000000000000..7649bb6ad7decf688209964fecefcd9cf8a529ae --- /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 0000000000000000000000000000000000000000..3c84edb0e6820517a8c6ac459b5dc117d5464511 --- /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 0000000000000000000000000000000000000000..66e9911e2cc27f23f6eff40ca81293ca1e743c52 --- /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 0000000000000000000000000000000000000000..ee8ecef830d69bb2f7a7a34d90ad908e2dcb6b5c --- /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 0000000000000000000000000000000000000000..ea745446096c9abd6b3a85206dfdea59babb2428 --- /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 0000000000000000000000000000000000000000..27ff352798c5c2cab5df2fd65727a82916c93129 --- /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 0000000000000000000000000000000000000000..f6958d0bedb8bbdc33c3d1c8e272be93a20a74af --- /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 0000000000000000000000000000000000000000..b8b2716e40c9006d714ca673ac385e4508a9dffa --- /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 0000000000000000000000000000000000000000..6e31ea3e615f2c21bba604907dd6d51221f87597 --- /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 0000000000000000000000000000000000000000..b9458d7142e2c011b09eef8a69d70c23167df4a0 --- /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 0000000000000000000000000000000000000000..ce04f2ac3563c01a0e6da63ba191c7fb706f1f2b --- /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 0000000000000000000000000000000000000000..b4b304b54e072c860ffcf48616420c5fc952efd9 --- /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 0000000000000000000000000000000000000000..5568c627292db6e58d560f7637022d527a73018b --- /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 0000000000000000000000000000000000000000..5d1c0862fbbc135565d67369887eb6ca06022577 --- /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 0000000000000000000000000000000000000000..e05a47fcd20a0d5b5ab5a4f7b90ab69cdad75c7a --- /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 0000000000000000000000000000000000000000..ae60bf59bafa2a1638a55ea74b2ff3a96130e4ee --- /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 0000000000000000000000000000000000000000..ad4800766473e83eff0d3dac83b2588ad33891e9 --- /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 0000000000000000000000000000000000000000..827e3c6eb1635b19a4160646f976744d93a000b4 --- /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 0000000000000000000000000000000000000000..a6dedfd9ab5a9b747bb14052e503f39443d463e9 --- /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 0000000000000000000000000000000000000000..d844fd2c60c7769e43bc7fc776a9f67a54b67acc --- /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 0000000000000000000000000000000000000000..87da14db01754625912f71813d36afd602f00f6e --- /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 0000000000000000000000000000000000000000..b379cad2a018fb0d6b58858989264aa8a3395695 --- /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 0000000000000000000000000000000000000000..1fca0b2b364a775916ca94be70c144bc9adfd9ee --- /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 0000000000000000000000000000000000000000..e83085577381f4251e0ce710997abf9ef419f16f --- /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 0000000000000000000000000000000000000000..8ffba8b382c838e2029d4d5b515ef58680e6f0ff --- /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 0000000000000000000000000000000000000000..b26d03cb96f910cca7057b46cf9ced99ebf25dc9 --- /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 0000000000000000000000000000000000000000..2d166ccba8bf9326aae045aa708a93ecb634cd35 --- /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 0000000000000000000000000000000000000000..c3dd67391138ace72d61d08bf41153c882dc5fc0 --- /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 0000000000000000000000000000000000000000..ead07acabd5a3e0bc5c87182bdb8ea16d2999b6f --- /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 0000000000000000000000000000000000000000..153442bd7d0aee27d251d8cb9398330a5007a8d7 --- /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 0000000000000000000000000000000000000000..609369bbeacb385292e6f835e6fb7161d5ba3118 --- /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 0000000000000000000000000000000000000000..8dfda9f595575a0859273013d8752a459de229e9 --- /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 0000000000000000000000000000000000000000..23935da0b899b08e073244b631ad5a4ecfa8d038 --- /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 0000000000000000000000000000000000000000..a54e1a6f20abc58dfe23d4daec2e57e95ea1349f --- /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 0000000000000000000000000000000000000000..db1cabaac1406570d93c68531c9e94c255a85160 --- /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 0000000000000000000000000000000000000000..d70d05076eef61872d7b839f4cf1a8e481bf946b --- /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 0000000000000000000000000000000000000000..445b812ca925ae6aff2274d1e1fcceaad5f35ced --- /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 0000000000000000000000000000000000000000..7e36cc9657662e44c43c14cd2a574af1ba8b3ba8 --- /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 0000000000000000000000000000000000000000..bd0d0e938fe08e34d71a31bb66c8905304e8c535 --- /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 0000000000000000000000000000000000000000..fe7ad9bf1becdbe4e7b8935d49ff7548d5954eb7 --- /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 0000000000000000000000000000000000000000..808fceb47ada7303133a9f75760b17c976795be0 --- /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 0000000000000000000000000000000000000000..4bcff42c1ef0705a813bb84f80a7f5960a3d994b --- /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 0000000000000000000000000000000000000000..d527736c740de207bdae72c3843c408343099ef5 --- /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 0000000000000000000000000000000000000000..126d5f59737b6d48c33dc72a8fa0b327f6c32fef --- /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 0000000000000000000000000000000000000000..8efa583e8850278b79a7ce640185f2f0e3b57d15 --- /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 0000000000000000000000000000000000000000..230c2abcf86e5568fe31850074260126ccb07723 --- /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 0000000000000000000000000000000000000000..ac7eba5ee82a9888b8bdc2b818657052d46734c6 --- /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 0000000000000000000000000000000000000000..6c8a7d1cbce2333421c7b8432d14d50859e2b7f5 --- /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 0000000000000000000000000000000000000000..301e5ee2f4096845e3c967ca0dfd9b62aa08fbc5 --- /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 0000000000000000000000000000000000000000..55e1a5a5588d45b90133b324f93abb4ea35eea87 --- /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 0000000000000000000000000000000000000000..f7f0a3a6a15e98b5e2deaa9114708082322a48a0 --- /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 0000000000000000000000000000000000000000..18e244224545f3bac0d7846140acaf4b60f32d73 --- /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 0000000000000000000000000000000000000000..1c3248404684e02a87f4f3bae2fce422e409ab72 --- /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 0000000000000000000000000000000000000000..632fd2f3c2a9da6d570118b548e3ba546f99b07c --- /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 0000000000000000000000000000000000000000..f99b49bf77d9a035497b01dfca6ee0887f20bc52 --- /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 0000000000000000000000000000000000000000..b460625d9be777e7b361fe3a84aecdd7c3a6a97d --- /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 0000000000000000000000000000000000000000..9506c1b85d231f87bf7a894ae8f242b2c2e87fb3 --- /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 0000000000000000000000000000000000000000..b3185aceffc52ff1dec855db299f4d49ed848523 --- /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 0000000000000000000000000000000000000000..461be1c9ad70d841356ffdcb29dada9211d391fd --- /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 0000000000000000000000000000000000000000..ee534ec0795b8407557d57814713e2748676356c --- /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 0000000000000000000000000000000000000000..73d6b348d48d976990a2c86b5a04a6ee8306bf24 --- /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 0000000000000000000000000000000000000000..22fd3651e854659677443d65b091c400bfd6df2c --- /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 0000000000000000000000000000000000000000..e84dcca348c56a2e9d483ab41a35015cd3c4a4bc --- /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 0000000000000000000000000000000000000000..767f7160356e225edc1db7170c1ad2b20172dbf8 --- /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 0000000000000000000000000000000000000000..fb6aa338bdce688d44795076ff983b28f32bb918 --- /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 0000000000000000000000000000000000000000..bb0edd8889a92743de76686c59175dabb8efd3c7 --- /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 0000000000000000000000000000000000000000..7df609c6d27c3dd68082c7d940a4dd85d68f6fb2 --- /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 0000000000000000000000000000000000000000..0f6019faaaa3b657d4799ff681c71e2fc427e696 --- /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 0000000000000000000000000000000000000000..229084095c3b45c97bb7e88513def9317ea5a770 --- /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 0000000000000000000000000000000000000000..458831d97f64c8f2811ff491b843e167cb7cf05f --- /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 0000000000000000000000000000000000000000..10b7ddf9945f3131abf9ac777dd06360aa28a831 --- /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 0000000000000000000000000000000000000000..de10923b93ccc994f34d8835749f926e9805e922 --- /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 0000000000000000000000000000000000000000..682b5a8c109a9e885b163db52dd864c3d51a3204 --- /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 0000000000000000000000000000000000000000..5ade7b021059bd7e13042bcdbaa145b635bc35c5 --- /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 0000000000000000000000000000000000000000..910eceea1af42c44d979c3a3eb35198b7f7762de --- /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 0000000000000000000000000000000000000000..be804d73001f4436bfcb4273cd3cafe48a2584d8 --- /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 0000000000000000000000000000000000000000..00dd5b4d5531be7dc6e7f72c88521b2045db19d2 --- /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');