summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/annexB/language/eval-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/eval-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/eval-code')
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js29
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js29
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js29
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js62
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js62
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js62
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js62
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js35
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js62
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js41
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js41
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js57
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js24
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js22
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js21
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js41
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js23
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js29
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js28
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js28
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js23
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-no-collision-in-strict-mode-strict.js24
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/shell.js14
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/switch-case-decl-nostrict.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/switch-dflt-decl-nostrict.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-block-scoping.js46
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-no-init.js24
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-no-init.js22
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-init.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-update.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-non-enumerable-global-init.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-no-init.js21
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-no-skip-try.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-block.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-in.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-of.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-switch.js41
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-try.js51
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err.js23
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-update.js29
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-block-scoping.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-no-skip-try.js53
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-block.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for.js49
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-try.js60
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err.js32
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-block-scoping.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-no-init.js28
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-non-enumerable-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-block-scoping.js50
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-no-init.js28
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js47
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/indirect/shell.js14
-rw-r--r--js/src/tests/test262/annexB/language/eval-code/shell.js0
476 files changed, 20296 insertions, 0 deletions
diff --git a/js/src/tests/test262/annexB/language/eval-code/browser.js b/js/src/tests/test262/annexB/language/eval-code/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/browser.js
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js b/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js
new file mode 100644
index 0000000000..4260564232
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-evaldeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Block statement
+ in eval code containing a function declaration
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err;
+
+eval('{ function f() {} }');
+
+try {
+ f;
+} catch (exception) {
+ err = exception;
+}
+
+assert.sameValue(err, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/browser.js b/js/src/tests/test262/annexB/language/eval-code/direct/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/browser.js
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js
new file mode 100644
index 0000000000..27dde2f65f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: A block-scoped binding is created (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+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() {
+ eval(
+ '{ 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/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..68ddb06e7c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,29 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ 'init = f;\
+ \
+ {\
+ function f() {}\
+ }{ function f() { } }'
+ );
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..a2644fcd64
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..2daa5c9126
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..bae56d9b36
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '{ 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/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..958db3cd13
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ 'var f = 123;\
+ init = f;{ function f() { } }'
+ );
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..34f4301f6c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '{ 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/eval-code/direct/func-block-decl-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js
new file mode 100644
index 0000000000..301da9a25a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..203f4619cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;{ function f() { } }after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..4f4e34e5fe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..ab535b814d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..c2374ae895
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..dc7da05847
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..d16957c668
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..1f7debf9dd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..ca87e65bd0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..db50751ee7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js
@@ -0,0 +1,29 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-block-decl-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js
new file mode 100644
index 0000000000..b48ae1660e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '{ 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/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js
new file mode 100644
index 0000000000..ab4f4c787b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..608471685f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..78075b67a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..b122a09227
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..6a8a3dc2de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..c8a445bde3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..b91fe29ce9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js
new file mode 100644
index 0000000000..7f617fda59
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..ce5e20cfae
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;if (true) function f() { } else function _f() {}after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..f64640a045
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..211a3ce0c3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..b1636d30ac
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..415575514b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..df7be27661
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..7c13f0bf39
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..867bd698a8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..5ace0cefe2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js
new file mode 100644
index 0000000000..4ce12a85c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js
new file mode 100644
index 0000000000..6a44335315
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..c965768369
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..4d2f769900
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..52b85a93cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..20940b96f5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..d717d59719
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..0f83c2e3cf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js
new file mode 100644
index 0000000000..f4082faa35
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..f53002a4c6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;if (false) function _f() {} else function f() { }after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..fbae9f3576
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..9c3bbfc98b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..1379520ad3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4371c9bf80
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..2464a27f3b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..ababc66716
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..5b51ba6fca
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..96807f992e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js
new file mode 100644
index 0000000000..59d3d0bc2c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js
new file mode 100644
index 0000000000..4187c63e20
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in eval code)
+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() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..354fe9d6bb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..fd03957d8b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..c6c0e2d941
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..8705895578
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..206aa99fd8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..cddd42ce9f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js
new file mode 100644
index 0000000000..30770f1d92
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..5df8c42e6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;if (true) function f() { } else ;after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..080bd25244
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..b0cc6e463b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5afbf9a836
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..0dd9a09a45
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..dc649e4656
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..0c36fb6f95
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..ea403cb698
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..308c01276a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js
new file mode 100644
index 0000000000..27a7bbb3e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js
new file mode 100644
index 0000000000..d660e42edb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in eval code)
+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() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..e0a6b3c8ad
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ 'init = f;\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { }'
+ );
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..72b2d2e2be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..85066a3b78
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..9ffa96945e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..758a8c545f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..a8a76bdbcc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js
new file mode 100644
index 0000000000..2eee349098
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..eb72a10dd9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;if (true) function f() { }after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..e93cd1eada
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..3819ca1bf1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..75600f772f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..667652faf1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..6580695602
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..d582221cc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..84e5447a1a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..ee99ef56bd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-decl-no-else-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js
new file mode 100644
index 0000000000..aa5a7629c7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js
new file mode 100644
index 0000000000..21aa62c841
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in eval code)
+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() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..8d153d8e32
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..28076cdfd5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..149b57f16c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..4c55632cc3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..2ddea80824
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..9bcc71893c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js
new file mode 100644
index 0000000000..10ae99630d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..b46e821b6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;if (false) ; else function f() { }after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..f4978f2488
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..de5cb215c8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..fdb4c3696d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..f05382f54c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..d9d673b891
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..b4ebb46742
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..76ed8c4ffb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js
@@ -0,0 +1,62 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..1eb39d30fa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js
new file mode 100644
index 0000000000..e4db767e06
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js
new file mode 100644
index 0000000000..54cd879734
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+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() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..6acc926d73
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..706f35141c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..f4ecb2da58
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..0be338236c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..eeac4cb415
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..3d1c625b90
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js
new file mode 100644
index 0000000000..a07ad2142d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..6e53d608e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..c62040f8fd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..e9a309f9a7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..58648dd301
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..2365574e72
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..546e26fc83
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..c53167f65f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..b0e7deb17f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..740e12f902
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-case-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js
new file mode 100644
index 0000000000..0a7971f061
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js
new file mode 100644
index 0000000000..690c57f19e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-block-scoping.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+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() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..d8b42c5dab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..d7dfedaadd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-block-fn-update.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ eval(
+ '{\
+ 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/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..2b80cd24e0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js
new file mode 100644
index 0000000000..2dfcdf7668
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-fn-update.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js
new file mode 100644
index 0000000000..13919adb04
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-no-init.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js
new file mode 100644
index 0000000000..37425a531a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-existing-var-update.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js
new file mode 100644
index 0000000000..440224c9c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-init.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ i. If varEnvRec is a global Environment Record, then
+ [...]
+ ii. Else,
+ i. Let bindingExists be varEnvRec.HasBinding(F).
+ ii. If bindingExists is false, then
+ i. Perform ! varEnvRec.CreateMutableBinding(F, true).
+ ii. Perform ! varEnvRec.InitializeBinding(F, undefined).
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js
new file mode 100644
index 0000000000..a12601f4be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-param.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Extension observed when there is a formal parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ eval(
+ 'init = f;switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ after = f;'
+ );
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(
+ typeof after, 'function', 'value is updated following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js
new file mode 100644
index 0000000000..c9e3e361f5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-no-skip-try.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js
new file mode 100644
index 0000000000..190319b3e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-block.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5bc34c75d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..5a0b73bfa2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js
new file mode 100644
index 0000000000..2aa2675c82
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-for.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..a7b71f4fb3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-switch.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js
new file mode 100644
index 0000000000..ab2e0d09cb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err-try.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js
new file mode 100644
index 0000000000..bb4a289e0e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-skip-early-err.case
+// - src/annex-b-fns/eval-func/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ eval(
+ '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/eval-code/direct/func-switch-dflt-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js
new file mode 100644
index 0000000000..1767b8b56b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-func-update.case
+// - src/annex-b-fns/eval-func/direct-switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+ eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' 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/eval-code/direct/global-block-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js
new file mode 100644
index 0000000000..5840488e11
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: A block-scoped binding is created (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+eval(
+ '{ function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..cd457a9b6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,24 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..01172ae73f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ '{ function f() { return "second declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..f30e873510
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js
@@ -0,0 +1,22 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");{ function f() { return "inner declaration"; } }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..9ebdbdadf4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ '{ function f() { return "inner declaration"; } }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..91ea8b26b8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });{ function f() { } }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..33fdb13721
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ '{ function f() { return "function declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..7204c5ff5b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });{ function f() { } }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..b653df30c5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js
@@ -0,0 +1,21 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..07ea9c9ddb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ '{ function f() { return "function declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js
new file mode 100644
index 0000000000..c623519d81
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..144a50ff8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..442effecd9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..ffb8f01ee1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..e12f3f9cdf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..3bdcbf5e55
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..13b0656643
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..0b3c4f3e34
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-block-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..072f3cefa1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js
@@ -0,0 +1,23 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");{ function f() { } }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js
new file mode 100644
index 0000000000..fce91ea18f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js
@@ -0,0 +1,29 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ '{ function f() { return "declaration"; } }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js
new file mode 100644
index 0000000000..bd1871bea6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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;
+
+eval(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else function _f() {}'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..c55406f3e6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..00bb3ebbe6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'if (true) function f() { return "second declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..6dbc46727a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else function _f() {}function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..3cf73b92c6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "inner declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..9b570eafc1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { } else function _f() {}'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..8da6813afe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'if (true) function f() { return "function declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..d307ae71ca
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { } else function _f() {}'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..1de4d888a7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..43575b820b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "function declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js
new file mode 100644
index 0000000000..b1f5d3e40c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..2ad6e35513
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..0f8badd847
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..fd73cacbf6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..6fd5517f51
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..4123b4d0de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..b85956ea8e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..52d2fa1a47
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..362e2c12bb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else function _f() {}assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js
new file mode 100644
index 0000000000..ba396ac827
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js
new file mode 100644
index 0000000000..c7660f4522
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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;
+
+eval(
+ 'if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..1cb1987281
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..d1f08ff72b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'if (false) function _f() {} else function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..45ab2ac914
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");if (false) function _f() {} else function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..a086f12d7c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) function _f() {} else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..2ed1e34431
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (false) function _f() {} else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..c31ccf055e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'if (false) function _f() {} else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..305db7f8c5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (false) function _f() {} else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..36263be7c4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..68bdffca61
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) function _f() {} else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js
new file mode 100644
index 0000000000..9f160ecd44
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..fe995f4bd4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..d4eb7c3028
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..6728a080a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..03a0fb211d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..fe1e9f54eb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..bd50eeed58
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..cb5d5a7c85
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..eaca19d8f0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) function _f() {} else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js
new file mode 100644
index 0000000000..c8a0558349
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) function _f() {} else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js
new file mode 100644
index 0000000000..84ac92489c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in eval code)
+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;
+
+eval(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else ;'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..531a25f086
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..ee47fed2e6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'if (true) function f() { return "second declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..5cc2909036
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else ;function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..25a8cd02b6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "inner declaration"; } else ;assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..3804c3c5d7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { } else ;'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..aef8081328
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'if (true) function f() { return "function declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..f76ac278be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { } else ;'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..4efa8e99cf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..343d40399c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "function declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js
new file mode 100644
index 0000000000..5202231f75
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..e46c03ff9a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..e42f9c995c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..03ee9404d5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..0c56312a50
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..04b01bfaa7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..c130d23ece
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..5787a86a77
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..0e5e13743d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else ;assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js
new file mode 100644
index 0000000000..22d6905e4c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "declaration"; } else ;assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js
new file mode 100644
index 0000000000..c2dec25011
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in eval code)
+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;
+
+eval(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..46b3fb179e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..46a6dc9861
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'if (true) function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..c5e44f12e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..f4cf01ce8a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..70eec47a74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..8e8922ac59
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'if (true) function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..36319fc697
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..9c03509911
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..001326e03a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js
new file mode 100644
index 0000000000..2c1121e2d6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..a7b457c08d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..d2c9f1e277
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..daf0b03731
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..61f4f03e60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..fc006bfe76
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..f532f79ae1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..4eeb4e633b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..5ebc6cfc4d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js
new file mode 100644
index 0000000000..1f396a89a5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (true) function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js
new file mode 100644
index 0000000000..c8e410fe38
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in eval code)
+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;
+
+eval(
+ 'if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..bd2ff524a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..da854b53df
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'if (false) ; else function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..4c434402ca
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");if (false) ; else function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..1835faf6a1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) ; else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..4f04be8aa3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (false) ; else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..297c307fa3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'if (false) ; else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..668b112545
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (false) ; else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..1f28a31233
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..cf1f9d8235
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) ; else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js
new file mode 100644
index 0000000000..ed46bb57a1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..4c2d8aa178
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..32a5b08edb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..6560a6dc6e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..44ce2beaed
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..0606b0417a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..523924c4d8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..081172cc60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..55e67d5a1b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) ; else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js
new file mode 100644
index 0000000000..55d7c28fdd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'if (false) ; else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js
new file mode 100644
index 0000000000..0bf1535d92
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +
+ '}\
+ '
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..1a6fbe35d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,28 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..26ae63c0bb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "second declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..9e987fa576
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..9162230086
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..9786610e2c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..2e399df93c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..7e7fcabd67
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..47fa604f5e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..8ee5f582c3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js
new file mode 100644
index 0000000000..229410f0fe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..1210887549
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..02bab370e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..cae6d7676f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..d703814eb3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..27f6664775
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..253ed73cc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..b2d625c02a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-switch-case-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..8a9c92b466
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js
new file mode 100644
index 0000000000..198649ed29
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js
new file mode 100644
index 0000000000..ba7a492e64
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +
+ '}\
+ '
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..f9237012f6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,28 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..52ed82190c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "second declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..d7b5a0786e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'assert.sameValue(f(), "outer declaration");switch (1) {' +
+ ' default:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..780449a32d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..f0da10714e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..b2fe4cbaaa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..e2ebe8da66
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..0d69f2e47b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+eval(
+ 'var f = 123;\
+ assert.sameValue(f, 123);switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..09da0ec602
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js
new file mode 100644
index 0000000000..5028ad5b23
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+eval(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..398cbc09d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..95bec64703
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '{\
+ 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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..34731cb943
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..7a87bd93dc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..cb4f0ab896
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..be6f13629d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..3cdad6b1d9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+eval(
+ '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/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..896ffef4d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/direct-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+eval(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js
new file mode 100644
index 0000000000..ea66a62173
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/direct-switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+eval(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js b/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js
new file mode 100644
index 0000000000..58d5a125b5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2023 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-globaldeclarationinstantiation
+description: Let binding collision with existing var declaration that was created for hoisted function.
+info: |
+ [...]
+ 3. For each element name of lexNames, do
+ a. If env.HasVarDeclaration(name) is true, throw a SyntaxError exception.
+flags: [noStrict]
+---*/
+
+eval('if (true) { function test262Fn() {} }');
+
+assert.throws(SyntaxError, function() {
+ $262.evalScript('var x; let test262Fn;');
+});
+
+assert.throws(ReferenceError, function() {
+ x;
+}, 'no bindings created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-no-collision-in-strict-mode-strict.js b/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-no-collision-in-strict-mode-strict.js
new file mode 100644
index 0000000000..da859c843d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/script-decl-lex-no-collision-in-strict-mode-strict.js
@@ -0,0 +1,24 @@
+'use strict';
+// Copyright (C) 2023 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-globaldeclarationinstantiation
+description: No let binding collision with existing var declaration due to strict-mode eval().
+info: |
+ PerformEval ( x, strictCaller, direct )
+
+ [...]
+ 16. If direct is true, then
+ a. Let lexEnv be NewDeclarativeEnvironment(runningContext's LexicalEnvironment).
+ [...]
+ 18. If strictEval is true, set varEnv to lexEnv.
+flags: [onlyStrict]
+---*/
+
+eval('if (true) { function test262Fn() {} }');
+
+$262.evalScript('let test262Fn = 1;');
+
+assert.sameValue(test262Fn, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/shell.js b/js/src/tests/test262/annexB/language/eval-code/direct/shell.js
new file mode 100644
index 0000000000..d8963d9d60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/shell.js
@@ -0,0 +1,14 @@
+// GENERATED, DO NOT EDIT
+// file: fnGlobalObject.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Produce a reliable global object
+defines: [fnGlobalObject]
+---*/
+
+var __globalObject = Function("return this;")();
+function fnGlobalObject() {
+ return __globalObject;
+}
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/switch-case-decl-nostrict.js b/js/src/tests/test262/annexB/language/eval-code/direct/switch-case-decl-nostrict.js
new file mode 100644
index 0000000000..cef6f4afa1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/switch-case-decl-nostrict.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-evaldeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `case` clause of a `switch` statement in eval code
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err;
+
+eval('\
+ switch (1) {\
+ case 1:\
+ function f() { }\
+ }\
+');
+
+try {
+ f;
+} catch (exception) {
+ err = exception;
+}
+
+assert.sameValue(err, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/switch-dflt-decl-nostrict.js b/js/src/tests/test262/annexB/language/eval-code/direct/switch-dflt-decl-nostrict.js
new file mode 100644
index 0000000000..d8becb2074
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/switch-dflt-decl-nostrict.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-evaldeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `default` clause of a `switch` statement in eval code
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err;
+
+eval('\
+ switch (1) {\
+ default:\
+ function f() { }\
+ }\
+');
+
+try {
+ f;
+} catch (exception) {
+ err = exception;
+}
+
+assert.sameValue(err, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js b/js/src/tests/test262/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
new file mode 100644
index 0000000000..11f306aecd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-variablestatements-in-catch-blocks
+description: Re-declaration of catch parameter
+info: |
+ [...]
+
+ This modified behaviour also applies to var and function declarations
+ introduced by direct evals contained within the Block of a Catch clause.
+ This change is accomplished by modifying the algorithm of 18.2.1.3 as follows:
+
+ Step 5.d.ii.2.a.i is replaced by:
+
+ i. If thisEnvRec is not the Environment Record for a Catch clause, throw a
+ SyntaxError exception.
+flags: [noStrict]
+---*/
+
+try {
+ throw null;
+} catch (err) {
+ eval('function err() {}');
+ eval('function* err() {}');
+ eval('async function err() {}');
+ eval('async function* err() {}');
+
+ eval('var err;');
+ eval('for (var err; false; ) {}');
+ eval('for (var err in []) {}');
+ eval('for (var err of []) {}');
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/browser.js b/js/src/tests/test262/annexB/language/eval-code/indirect/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/browser.js
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-block-scoping.js
new file mode 100644
index 0000000000..dee07e058a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-block-scoping.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: A block-scoped binding is created (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+(0,eval)(
+ '{ function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..af9d45557c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,24 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..750dcbc80a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-block-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ '{ function f() { return "second declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..5b9b87599d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-no-init.js
@@ -0,0 +1,22 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");{ function f() { return "inner declaration"; } }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..a4a3b1e39c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-fn-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ '{ function f() { return "inner declaration"; } }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..0ffa7a899e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-init.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });{ function f() { } }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..1f53ce9d32
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ '{ function f() { return "function declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..37bbbfb131
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });{ function f() { } }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..2144c040a2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-no-init.js
@@ -0,0 +1,21 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Existing variable binding is not modified (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..6b6d13d6cf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-var-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ '{ function f() { return "function declaration"; } }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-init.js
new file mode 100644
index 0000000000..502fa612fe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });{ function f() { } }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..ab65c646ae
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-no-skip-try.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..42b6330b97
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-block.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..b24bbb3f9b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..0ca9f52538
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..05bb08ccb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..885b6be204
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-switch.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..23251e6323
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-try.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-block-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..2a05b83d93
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err.js
@@ -0,0 +1,23 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");{ function f() { } }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-update.js
new file mode 100644
index 0000000000..a8ea533e4c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-update.js
@@ -0,0 +1,29 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in eval code containing a function declaration)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ '{ function f() { return "declaration"; } }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-block-scoping.js
new file mode 100644
index 0000000000..2bd1ad9a4b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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;
+
+(0,eval)(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else function _f() {}'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..410903ce55
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..9157174c6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'if (true) function f() { return "second declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..cc67626ccb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else function _f() {}function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..f63d933e4b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "inner declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..0f6e39cbcd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { } else function _f() {}'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..6899ce3b0d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..79d79148e1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { } else function _f() {}'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..f20019e58a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..2521f2693a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; } else function _f() {}'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-init.js
new file mode 100644
index 0000000000..eb88aedf98
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { } else function _f() {}'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..7c3e4152e0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..7c7c5544ae
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..489c55e0e1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..75c6882953
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..0fa2fbac21
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..a4a9497966
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..afae753fb0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..48b4d66397
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else function _f() {}assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-update.js
new file mode 100644
index 0000000000..418be65581
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-block-scoping.js
new file mode 100644
index 0000000000..f9dd218ded
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code)
+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;
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..8fc96c150c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..873b7fdcec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..9b98e79b16
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");if (false) function _f() {} else function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..c796f2885d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..f70c8a72de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (false) function _f() {} else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..a43f415cd2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..771682c51a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (false) function _f() {} else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..5fa68bd4ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..0ba642d928
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-init.js
new file mode 100644
index 0000000000..b9764fb934
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (false) function _f() {} else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..0dc4019426
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..673a3b14c4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..d32e4846a7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..8906db6b0e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..9f871505a2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..e9b0a9a32a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..07d3c36894
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..a324b1b1e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) function _f() {} else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-update.js
new file mode 100644
index 0000000000..3c5e3643cf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) function _f() {} else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-block-scoping.js
new file mode 100644
index 0000000000..42be9b1467
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in eval code)
+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;
+
+(0,eval)(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else ;'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..8f547b4aba
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..4e4c6f7549
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'if (true) function f() { return "second declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..0dce1c9149
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else ;function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..e150620612
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "inner declaration"; } else ;assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..eb57ab56ab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { } else ;'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..db469b6aa4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..33658df992
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { } else ;'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..cc63ca1f1a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..d2b1f06fc0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; } else ;'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-init.js
new file mode 100644
index 0000000000..f060b0924b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { } else ;'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..3f0cf3f2d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..1b2e82de18
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..6e748fde84
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..f3e8a8c965
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..5b3d8b0dda
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..ff2e160658
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..0612d7f5af
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..d79c826ff2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else ;assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-update.js
new file mode 100644
index 0000000000..452aaceff3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "declaration"; } else ;assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-block-scoping.js
new file mode 100644
index 0000000000..66ba3a21b6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in eval code)
+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;
+
+(0,eval)(
+ 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..7d6a39a424
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..b30c10ed7f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'if (true) function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..185b33268b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..8bf0e03a7f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..1d4b99ce6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (true) function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..8cec9721a6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..f88664333c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (true) function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..b0cd617454
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..96d860be07
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-init.js
new file mode 100644
index 0000000000..5306f61dcc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (true) function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..270e6b0b33
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..59392a8c3f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..26a27767e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..468bfcb30b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..557dcc13ac
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..c710a3a748
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..93311c721e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..432a0cec8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-update.js
new file mode 100644
index 0000000000..7128f2eaab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (true) function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-block-scoping.js
new file mode 100644
index 0000000000..281ec9a2ef
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-block-scoping.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in eval code)
+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;
+
+(0,eval)(
+ 'if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }'
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..0eb87a5311
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..4e22fc5ad4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'if (false) ; else function f() { return "second declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..1798f83625
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");if (false) ; else function f() { return "inner declaration"; }function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..755d56c0d9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) ; else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..a16c613523
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });if (false) ; else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..bf0750d6b4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-global-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'if (false) ; else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..e59344134d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });if (false) ; else function f() { }'
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..249fab4e6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..2eebbf0d0f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) ; else function f() { return "function declaration"; }'
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-init.js
new file mode 100644
index 0000000000..bb35c760b3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });if (false) ; else function f() { }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..c53c08d910
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-no-skip-try.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..bbf00049aa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..d7fedb42e6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..ed49e8a4b1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..b8f9a70732
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..5469f6c82c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..fdffbd867a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
@@ -0,0 +1,60 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..0002212e06
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) ; else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-update.js
new file mode 100644
index 0000000000..6ffd11526b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in eval code)
+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.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'if (false) ; else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-block-scoping.js
new file mode 100644
index 0000000000..12fd087b47
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-block-scoping.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +
+ '}\
+ '
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..411271208f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,28 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..a30594f3cd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-block-fn-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "second declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..8a442f14d1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..b4602a7b92
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..e19cebf7eb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..857cabdc91
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..0e55e7e1ff
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..130db94796
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..c12fc70170
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-var-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-init.js
new file mode 100644
index 0000000000..2629a27034
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..6d0e7b9b5c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..4c48bd812e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..c832db3e5f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..1ea7359ea1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..9d3a6fbfec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..a9b929ae94
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..d58c513efa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-case-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..7827b54806
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' +
+ ' case 1:' +
+ ' function f() { }' +
+ '}\
+ assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-update.js
new file mode 100644
index 0000000000..6bdf8da365
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' case 1:' +
+ ' function f() { return "declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-block-scoping.js
new file mode 100644
index 0000000000..e844088498
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-block-scoping.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-block-scoping.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+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;
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +
+ '}\
+ '
+);
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..084d141e84
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-no-init.js
@@ -0,0 +1,28 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f, undefined);\
+ \
+ {\
+ function f() {}\
+ }switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..6a2bebe5cb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-block-fn-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-block-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "second declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..0ce42cabab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'assert.sameValue(f(), "outer declaration");switch (1) {' +
+ ' default:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-update.js
new file mode 100644
index 0000000000..5229335927
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-fn-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "inner declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "inner declaration");\
+ \
+ function f() {\
+ return "outer declaration";\
+ }'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-init.js
new file mode 100644
index 0000000000..d6f470f684
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: false\
+ }, { restore: true });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-update.js
new file mode 100644
index 0000000000..90813461da
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-global-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-global-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: function() { return 'Another function'; },
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..f1efedc74d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+Object.defineProperty(fnGlobalObject(), 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, "x", "binding is not reinitialized");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: false,\
+ writable: true,\
+ configurable: true\
+ }, { restore: true });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, "function");
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-no-init.js
new file mode 100644
index 0000000000..af7dde5d00
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-no-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ a. If declaredFunctionOrVarNames does not contain F, then
+ [...]
+---*/
+
+(0,eval)(
+ 'var f = 123;\
+ assert.sameValue(f, 123);switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-update.js
new file mode 100644
index 0000000000..9bcc7f911f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-existing-var-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-existing-var-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "function declaration"; }' +
+ '}\
+ '
+);
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-init.js
new file mode 100644
index 0000000000..944f136303
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-init.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ i. If varEnvRec is a global Environment Record, then
+ i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true).
+ [...]
+
+---*/
+
+(0,eval)(
+ 'var global = fnGlobalObject();\
+ assert.sameValue(f, undefined, "binding is initialized to `undefined`");\
+ \
+ verifyProperty(global, "f", {\
+ enumerable: true,\
+ writable: true,\
+ configurable: true\
+ });switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ '
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-no-skip-try.js
new file mode 100644
index 0000000000..169b929df1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-no-skip-try.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-block.js
new file mode 100644
index 0000000000..6eb580a334
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-block.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '{\
+ 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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..cd97de3069
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-in.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..954727e550
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for-of.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for.js
new file mode 100644
index 0000000000..504b53166b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-for.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..76eb99d49c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-switch.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-try.js
new file mode 100644
index 0000000000..6082a67782
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err-try.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(0,eval)(
+ '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/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err.js
new file mode 100644
index 0000000000..83737f47a6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-skip-early-err.case
+// - src/annex-b-fns/eval-global/indirect-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 eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ body, then
+ [...]
+---*/
+
+(0,eval)(
+ 'let f = 123;\
+ assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' +
+ ' default:' +
+ ' function f() { }' +
+ '}\
+ assert.sameValue(f, 123, "value is not updated following evaluation");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-update.js
new file mode 100644
index 0000000000..052721cb11
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/eval-global-update.case
+// - src/annex-b-fns/eval-global/indirect-switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope)
+esid: sec-web-compat-evaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.3 Changes to EvalDeclarationInstantiation
+
+ [...]
+ b. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+(0,eval)(
+ 'switch (1) {' +
+ ' default:' +
+ ' function f() { return "declaration"; }' +
+ '}\
+ assert.sameValue(typeof f, "function");\
+ assert.sameValue(f(), "declaration");'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/eval-code/indirect/shell.js b/js/src/tests/test262/annexB/language/eval-code/indirect/shell.js
new file mode 100644
index 0000000000..d8963d9d60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/indirect/shell.js
@@ -0,0 +1,14 @@
+// GENERATED, DO NOT EDIT
+// file: fnGlobalObject.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Produce a reliable global object
+defines: [fnGlobalObject]
+---*/
+
+var __globalObject = Function("return this;")();
+function fnGlobalObject() {
+ return __globalObject;
+}
diff --git a/js/src/tests/test262/annexB/language/eval-code/shell.js b/js/src/tests/test262/annexB/language/eval-code/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/eval-code/shell.js