summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/annexB/language/global-code
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js35
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js24
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/script-decl-lex-collision.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/shell.js14
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js34
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js34
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js32
155 files changed, 6622 insertions, 0 deletions
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js
new file mode 100644
index 0000000000..0e8679da87
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: A block-scoped binding is created (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+{
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..0db1e5dfe4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..42ac287bf8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+{
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..0e93d6138a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js
new file mode 100644
index 0000000000..b84056f1d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js
new file mode 100644
index 0000000000..8f01bd2011
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..b5e877aca1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js
new file mode 100644
index 0000000000..01c02d7211
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js
@@ -0,0 +1,24 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js
new file mode 100644
index 0000000000..ed0528ff89
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js
new file mode 100644
index 0000000000..5bee96bb60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js
new file mode 100644
index 0000000000..99f4644560
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+{
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js
new file mode 100644
index 0000000000..97340c7ef6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..44c43c6de6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..c17c700ebe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js
new file mode 100644
index 0000000000..cd18e31083
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+{
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..69b17807d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js
new file mode 100644
index 0000000000..11f6f3f9f6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js
new file mode 100644
index 0000000000..bf2e8f2d78
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+{
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js
new file mode 100644
index 0000000000..fcd9089de9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/browser.js b/js/src/tests/test262/annexB/language/global-code/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/browser.js
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js
new file mode 100644
index 0000000000..cc91a5554b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else function _f() {}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..8c0ce24631
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..3607d616d5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..72391ceb50
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js
new file mode 100644
index 0000000000..f2361bc455
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js
new file mode 100644
index 0000000000..1782710215
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..127566889e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js
new file mode 100644
index 0000000000..0e2df04954
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js
new file mode 100644
index 0000000000..fab9e891e9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js
new file mode 100644
index 0000000000..33e4013793
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js
new file mode 100644
index 0000000000..94f64755ad
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; } else function _f() {}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js
new file mode 100644
index 0000000000..35da032367
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..8b56b4ffda
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..833613ba1d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js
new file mode 100644
index 0000000000..12b21152a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { } else function _f() {}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..ae3caf3724
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js
new file mode 100644
index 0000000000..df776a337d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js
new file mode 100644
index 0000000000..96b6643351
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { } else function _f() {}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js
new file mode 100644
index 0000000000..00631eb1cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js
new file mode 100644
index 0000000000..32fabf1305
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5013acff1d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..8586d1fab5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (false) function _f() {} else function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..fb382075d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js
new file mode 100644
index 0000000000..20af165cb9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js
new file mode 100644
index 0000000000..1d38cf094f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..b6ac9ea951
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js
new file mode 100644
index 0000000000..8e4b49da66
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js
new file mode 100644
index 0000000000..017c3a2df5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js
new file mode 100644
index 0000000000..1fd73e6b46
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js
new file mode 100644
index 0000000000..0905343b7b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (false) function _f() {} else function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js
new file mode 100644
index 0000000000..1d2f05ebee
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..e01be3834a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..9f0f462003
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js
new file mode 100644
index 0000000000..78d783a75f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (false) function _f() {} else function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..29117eac4c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js
new file mode 100644
index 0000000000..128c69896f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js
new file mode 100644
index 0000000000..4d222b42da
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (false) function _f() {} else function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js
new file mode 100644
index 0000000000..a52a234916
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js
new file mode 100644
index 0000000000..63e8de77fd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else ;
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..2ddbe61e82
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..ddea624e1a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..e660d2190e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js
new file mode 100644
index 0000000000..6747bc3dd6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js
new file mode 100644
index 0000000000..e3d3692688
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..51dc2295f7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js
new file mode 100644
index 0000000000..b441d16b9a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js
new file mode 100644
index 0000000000..134d0331a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js
new file mode 100644
index 0000000000..95283ace21
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js
new file mode 100644
index 0000000000..9ddc061cba
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; } else ;
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js
new file mode 100644
index 0000000000..1b9ee82751
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..d8fbea333c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..37b8073f36
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js
new file mode 100644
index 0000000000..76fce1ad05
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { } else ;
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..02c18446ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js
new file mode 100644
index 0000000000..7590052baf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js
new file mode 100644
index 0000000000..cdfc04f1f3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { } else ;
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js
new file mode 100644
index 0000000000..017fb8a561
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js
new file mode 100644
index 0000000000..aaa3260e4f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..0529a27dbb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..2eaa65ac7e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..6fcdab9472
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js
new file mode 100644
index 0000000000..13efde00e9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js
new file mode 100644
index 0000000000..20ccf38a8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..476cb7d657
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js
new file mode 100644
index 0000000000..607e4a8d5d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js
new file mode 100644
index 0000000000..f4de295595
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js
new file mode 100644
index 0000000000..93e3e7d620
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js
new file mode 100644
index 0000000000..51b0fa60a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js
new file mode 100644
index 0000000000..efe8ffb573
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..8e8d983772
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..bedf210a6f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js
new file mode 100644
index 0000000000..bc51acc91c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..42f11c6d8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js
new file mode 100644
index 0000000000..ba28687329
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js
new file mode 100644
index 0000000000..b89fd617c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js
new file mode 100644
index 0000000000..9f796b80a4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js
new file mode 100644
index 0000000000..82560a2ed6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5619dbc4c3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..0eaf33f549
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (false) ; else function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..40a1c7cd33
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js
new file mode 100644
index 0000000000..45f31b1162
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js
new file mode 100644
index 0000000000..7b7d2b192d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..32adf96121
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js
new file mode 100644
index 0000000000..6fc5a31baa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js
new file mode 100644
index 0000000000..12db70333c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js
new file mode 100644
index 0000000000..fdd0742747
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js
new file mode 100644
index 0000000000..cc9df07afd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (false) ; else function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js
new file mode 100644
index 0000000000..3e5c4214fa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5003bac76f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..eb5429ed6e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js
new file mode 100644
index 0000000000..cc7fbebe59
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (false) ; else function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..0a679ec65e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js
new file mode 100644
index 0000000000..d9accdb9c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js
new file mode 100644
index 0000000000..5ab1910dbe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (false) ; else function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js
new file mode 100644
index 0000000000..19faf6ae34
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/script-decl-lex-collision.js b/js/src/tests/test262/annexB/language/global-code/script-decl-lex-collision.js
new file mode 100644
index 0000000000..d67ec17f8b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/script-decl-lex-collision.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-globaldeclarationinstantiation
+description: Let binding collision with existing var declaration that was created for hoisted function.
+info: |
+ [...]
+ 3. For each element name of lexNames, do
+ a. If env.HasVarDeclaration(name) is true, throw a SyntaxError exception.
+flags: [noStrict]
+---*/
+
+if (true) {
+ function test262Fn() {}
+}
+
+assert.throws(SyntaxError, function() {
+ $262.evalScript('var x; let test262Fn;');
+});
+
+assert.throws(ReferenceError, function() {
+ x;
+}, 'no bindings created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/shell.js b/js/src/tests/test262/annexB/language/global-code/shell.js
new file mode 100644
index 0000000000..d8963d9d60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/shell.js
@@ -0,0 +1,14 @@
+// GENERATED, DO NOT EDIT
+// file: fnGlobalObject.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Produce a reliable global object
+defines: [fnGlobalObject]
+---*/
+
+var __globalObject = Function("return this;")();
+function fnGlobalObject() {
+ return __globalObject;
+}
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js
new file mode 100644
index 0000000000..b03d2a4dcc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+switch (1) {
+ case 1:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..f1bbef9bc2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..3160336f6c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+switch (1) {
+ case 1:
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..7265812f54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js
new file mode 100644
index 0000000000..feec1ea5f4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js
new file mode 100644
index 0000000000..b2526706ce
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..8e2679a2c4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js
new file mode 100644
index 0000000000..f61abec5b4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js
new file mode 100644
index 0000000000..390f21f73c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js
new file mode 100644
index 0000000000..7e188568aa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js
new file mode 100644
index 0000000000..666660a8a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+switch (1) {
+ case 1:
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js
new file mode 100644
index 0000000000..51dc7e6830
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..2eb9205520
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4a6f0f0816
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js
new file mode 100644
index 0000000000..854d86d587
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..9979075710
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js
new file mode 100644
index 0000000000..431c89fcc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js
new file mode 100644
index 0000000000..a85069836a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js
new file mode 100644
index 0000000000..57ca37845c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js
new file mode 100644
index 0000000000..98fdab7428
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+switch (1) {
+ default:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5a8d67620a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..2e6ffb57a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+switch (1) {
+ default:
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..de237db14c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js
new file mode 100644
index 0000000000..bdc848d629
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js
new file mode 100644
index 0000000000..c8374585e5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..355df49ab1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js
new file mode 100644
index 0000000000..617855bc74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js
new file mode 100644
index 0000000000..bc78d09851
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js
new file mode 100644
index 0000000000..daac57ba41
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js
new file mode 100644
index 0000000000..eb26d12e12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+switch (1) {
+ default:
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js
new file mode 100644
index 0000000000..8bc922544a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..bbc24f619e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4e603f783e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js
new file mode 100644
index 0000000000..0c838ac8de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..b7ae155f9d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js
new file mode 100644
index 0000000000..ae1530120d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js
new file mode 100644
index 0000000000..f3a91763ab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js
new file mode 100644
index 0000000000..72fc86d451
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);