summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/annexB/language/function-code
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/annexB/language/function-code
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/annexB/language/function-code')
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js51
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js46
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js46
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js20
-rw-r--r--js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js35
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js39
161 files changed, 7277 insertions, 0 deletions
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js
new file mode 100644
index 0000000000..6700dcec8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: A block-scoped binding is created (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+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, varBinding;
+
+(function() {
+
+
+ {
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..19c91c981a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..4a090ca5a9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ {
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..154d6d0cd4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js
new file mode 100644
index 0000000000..27b1ea9276
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js
new file mode 100644
index 0000000000..50547ff772
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js
new file mode 100644
index 0000000000..532e46b053
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js
new file mode 100644
index 0000000000..ce86d2797b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js
new file mode 100644
index 0000000000..e0cf6d2e54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-arguments.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js
new file mode 100644
index 0000000000..14772af5ff
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Functions named 'arguments' have legacy hoisting semantics
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [noStrict]
+info: |
+ FunctionDeclarationInstantiation ( _func_, _argumentsList_ )
+
+ [...]
+ 7. Let _parameterNames_ be the BoundNames of _formals_.
+ [...]
+ 22. If argumentsObjectNeeded is true, then
+ f. Append "arguments" to parameterNames.
+
+ Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the |FunctionDeclaration| _f_ with a |VariableStatement| that has _F_
+ as a |BindingIdentifier| would not produce any Early Errors for _func_ and _F_ is
+ not an element of _parameterNames_, then
+ [...]
+---*/
+
+// Simple parameters
+(function() {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+// Single named parameter
+(function(x) {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+// Non-simple parameters
+(function(..._) {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js
new file mode 100644
index 0000000000..b6518043ca
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js
new file mode 100644
index 0000000000..f97a906e23
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..aed0866402
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..e715cb5204
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js
new file mode 100644
index 0000000000..9a85550de4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..cdd96eb131
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js
new file mode 100644
index 0000000000..7acfcdcd79
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/block-decl-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js
new file mode 100644
index 0000000000..28b12bc208
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js
new file mode 100644
index 0000000000..db5ac4fbab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js
new file mode 100644
index 0000000000..9b621f3e09
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js b/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
new file mode 100644
index 0000000000..c7e85de89a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2018 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ Nested function declarations, the second declaration is not Annex-B applicable.
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ a. For each FunctionDeclaration f that is directly contained in the
+ StatementList of a Block, CaseClause, or DefaultClause, do
+ i. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of parameterNames, then
+ ...
+flags: [noStrict]
+---*/
+
+function g() {
+ // Create an outer block-statement.
+ {
+ // A lexically declared function declaration.
+ // This function is applicable for Annex-B semantics.
+ function f() { return 1; }
+
+ // An inner block-statement with another function declaration.
+ // This function is not applicable for Annex-B semantics, because
+ // replacing it with |var f| would result in a SyntaxError.
+ {
+ function f() { return 2; }
+ }
+ }
+
+ assert.sameValue(f(), 1);
+}
+
+g();
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js
new file mode 100644
index 0000000000..6c4a289682
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Block statement
+ in function code containing a function declaration
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ {
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/browser.js b/js/src/tests/test262/annexB/language/function-code/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/browser.js
diff --git a/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js
new file mode 100644
index 0000000000..1e3a163cd3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2019 Adrian Heine. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: In non-strict mode, duplicate LexicallyDeclaredNames in a block are allowed if they are bound by FunctionDeclarations
+esid: sec-block-duplicates-allowed-static-semantics
+es6id: B.3.3.4
+flags: [noStrict]
+info: |
+ B.3.3.4 Changes to Block Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ Block: {StatementList}
+
+ It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+---*/
+
+{ function a() {} function a() {} }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js
new file mode 100644
index 0000000000..2c03663358
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 Adrian Heine. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: In non-strict mode, duplicate LexicallyDeclaredNames in a switch statement's CaseBlock are allowed if they are bound by FunctionDeclarations
+esid: sec-switch-duplicates-allowed-static-semantics
+es6id: B.3.3.5
+flags: [noStrict]
+info: |
+ B.3.3.4 Changes to Block Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ Block: {StatementList}
+
+ It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+
+
+ B.3.3.5 Changes to switch Statement Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ SwitchStatement: switch ( Expression ) CaseBlock
+
+ It is a Syntax Error if the LexicallyDeclaredNames of CaseBlock contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+---*/
+
+let x
+switch (x) {
+case 1:
+ function a() {}
+case 2:
+ function a() {}
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
new file mode 100644
index 0000000000..298013f304
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in function 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, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else function _f() {}
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..351f7cde4b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..9de2d7e5d5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; } else function _f() {}
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..5974dc3858
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js
new file mode 100644
index 0000000000..a15ad9f4f1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js
new file mode 100644
index 0000000000..53ad53abf9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js
new file mode 100644
index 0000000000..40541fdc07
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; } else function _f() {}
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js
new file mode 100644
index 0000000000..18f1176553
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js
new file mode 100644
index 0000000000..7d22f11253
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js
new file mode 100644
index 0000000000..8c3bc7ebb7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js
new file mode 100644
index 0000000000..b5b0aefa84
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5772f7b450
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..659b967860
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js
new file mode 100644
index 0000000000..0b196cdbd6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..8a1ac1fb56
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js
new file mode 100644
index 0000000000..1c72b31349
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-a-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js
new file mode 100644
index 0000000000..54639c774f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js
new file mode 100644
index 0000000000..10be89c4bf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js
new file mode 100644
index 0000000000..2196f3670d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js
new file mode 100644
index 0000000000..479cef98b6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in function 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, varBinding;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..1dfd9399c1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..720594506b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (false) function _f() {} else function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..1f4137a1e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js
new file mode 100644
index 0000000000..5bd63bde74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js
new file mode 100644
index 0000000000..48a39bf46d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js
new file mode 100644
index 0000000000..6a33e16a67
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js
new file mode 100644
index 0000000000..d1b30c8891
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js
new file mode 100644
index 0000000000..4e2237f997
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js
new file mode 100644
index 0000000000..9a9b036e02
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js
new file mode 100644
index 0000000000..27323b1de3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..f9f4bf4e0c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..de6f1953c0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js
new file mode 100644
index 0000000000..7808944a3e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..b1c502a663
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js
new file mode 100644
index 0000000000..2a72aeb9ba
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-decl-b-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js
new file mode 100644
index 0000000000..e3c1a40a12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js
new file mode 100644
index 0000000000..8d4f4e1ebf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js
new file mode 100644
index 0000000000..ddb511d8d4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js
new file mode 100644
index 0000000000..1a0b2460a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in function 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, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else ;
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..b74fbff156
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..8d9a65d180
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; } else ;
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..b4d745aa51
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; } else ;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js
new file mode 100644
index 0000000000..f95dae5053
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; } else ;
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js
new file mode 100644
index 0000000000..61dedaada8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js
new file mode 100644
index 0000000000..296e77ea3c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; } else ;
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js
new file mode 100644
index 0000000000..21bb3ff317
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js
new file mode 100644
index 0000000000..6e6d3d6f76
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js
new file mode 100644
index 0000000000..c5b36b9656
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js
new file mode 100644
index 0000000000..c34431e6fc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..58c7b94769
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..ddc0028253
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js
new file mode 100644
index 0000000000..e1c4f648de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..cb73605211
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js
new file mode 100644
index 0000000000..7de1c6c72f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-else-stmt-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js
new file mode 100644
index 0000000000..0c86eea6a5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js
new file mode 100644
index 0000000000..ca71166ab5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js
new file mode 100644
index 0000000000..5d784877be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; } else ;
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js
new file mode 100644
index 0000000000..9fb86796d4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in function 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, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..4c4f4d622d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..6b22f948b0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..c0d9cb2d12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js
new file mode 100644
index 0000000000..e90a392aa4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js
new file mode 100644
index 0000000000..9f7d817a74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js
new file mode 100644
index 0000000000..50f36bdcc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js
new file mode 100644
index 0000000000..1e83b641d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js
new file mode 100644
index 0000000000..2b5b9b54f2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js
new file mode 100644
index 0000000000..f69e1063be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js
new file mode 100644
index 0000000000..050d97c218
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..97fe839a55
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4fb50227e5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js
new file mode 100644
index 0000000000..1029f5f034
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..1b0c0b8d78
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js
new file mode 100644
index 0000000000..562e29900b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-decl-no-else-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js
new file mode 100644
index 0000000000..00459a239a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js
new file mode 100644
index 0000000000..00ba2976ac
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js
new file mode 100644
index 0000000000..5038274c87
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js
new file mode 100644
index 0000000000..e8850b9c51
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in function 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, varBinding;
+
+(function() {
+
+
+ if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..b3292466ed
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..ce84f7ed1c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (false) ; else function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..5c649b8ccc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (false) ; else function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js
new file mode 100644
index 0000000000..2bdf2fadb7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js
new file mode 100644
index 0000000000..0d9635df28
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js
new file mode 100644
index 0000000000..03f9416a2a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js
new file mode 100644
index 0000000000..3816385413
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js
new file mode 100644
index 0000000000..a574afb7f3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js
new file mode 100644
index 0000000000..5e86815aec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js
new file mode 100644
index 0000000000..fbce2691eb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..85ecefb417
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..1c6ef0d10b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js
new file mode 100644
index 0000000000..4e80a4479e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..9d97fa40f2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js
new file mode 100644
index 0000000000..ed0d06d49b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/if-stmt-else-decl-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js
new file mode 100644
index 0000000000..4a8ac7ef54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js
new file mode 100644
index 0000000000..770713d5c1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js
new file mode 100644
index 0000000000..05feeb50a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in function 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.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/shell.js b/js/src/tests/test262/annexB/language/function-code/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/shell.js
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js
new file mode 100644
index 0000000000..9a1d776960
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `case` clause of a `switch` statement in function code
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js
new file mode 100644
index 0000000000..5388791b85
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+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, varBinding;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..15ef7e3fbc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..f667bf7507
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ switch (1) {
+ case 1:
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..04d8d3e0c6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js
new file mode 100644
index 0000000000..e76b044eb1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js
new file mode 100644
index 0000000000..603f17b7fc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js
new file mode 100644
index 0000000000..ec37b546af
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js
new file mode 100644
index 0000000000..9fa416ad1b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js
new file mode 100644
index 0000000000..4edbd0a847
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js
new file mode 100644
index 0000000000..f6ca9c65e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js
new file mode 100644
index 0000000000..5b8f50ed2f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..3aba8da1c9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..f949da87cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js
new file mode 100644
index 0000000000..5ff85c5766
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..1ecf8cbbef
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js
new file mode 100644
index 0000000000..eee62b5561
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/switch-case-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js
new file mode 100644
index 0000000000..87d64e1536
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js
new file mode 100644
index 0000000000..2d5699418b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js
new file mode 100644
index 0000000000..cea6aa60a9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js
new file mode 100644
index 0000000000..fbcfb8ca05
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `default` clause of a `switch` statement in function code
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js
new file mode 100644
index 0000000000..c18abba71b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+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, varBinding;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = 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(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..57d48d90ef
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..83b4326ac3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ switch (1) {
+ default:
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..04afab4d5e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js
new file mode 100644
index 0000000000..b88bf18fed
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js
new file mode 100644
index 0000000000..cb3c100f7f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js
new file mode 100644
index 0000000000..ca87f7f957
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js
new file mode 100644
index 0000000000..cab3d64da2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js
new file mode 100644
index 0000000000..93d2811ed0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js
new file mode 100644
index 0000000000..e4744d252a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js
new file mode 100644
index 0000000000..14f8113e92
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..0daaf4dbbe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..ce5b5d9d3b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js
new file mode 100644
index 0000000000..3fce6ca7fe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..41247388b1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js
new file mode 100644
index 0000000000..888accb356
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ 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.
+---*/
+
+(function() {
+ 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/function-code/switch-dflt-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js
new file mode 100644
index 0000000000..e18ab0ad06
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/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 function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js
new file mode 100644
index 0000000000..cc12b43957
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js
new file mode 100644
index 0000000000..08ab434109
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);