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');