summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/annexB
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/annexB
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--js/src/tests/test262/annexB/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Array/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Array/from/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Array/from/iterator-method-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/Array/from/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Array/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/B.2.4.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/nan.js17
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/return-value.js43
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/this-not-date.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/B.2.5.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-not-date.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-nan.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-valid.js21
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/time-clip.js36
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-nan.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-absolute.js44
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-relative.js47
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-to-number-err.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/prop-desc.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/value.js16
-rw-r--r--js/src/tests/test262/annexB/built-ins/Date/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-body.js22
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-params.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-body.js22
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-params.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-params.js27
-rw-r--r--js/src/tests/test262/annexB/built-ins/Function/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Object/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Object/is/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Object/is/emulates-undefined.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/Object/is/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/Object/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-control-escape-russian-letter.js55
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-class-range.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-not-capturing.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class-range.js26
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class.js56
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape.js16
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape.js16
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/incomplete_hex_unicode_escape.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js35
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js33
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js63
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js33
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js45
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js64
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js76
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js64
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js42
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js62
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js42
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js62
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js42
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js62
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js42
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js62
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/named-groups/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed-lookbehind.js17
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed.js27
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/named-groups/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/Symbol.match-getter-recompiles-source.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/toint32-limit-recompiles-source.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/B.RegExp.prototype.compile.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/duplicate-named-capturing-groups-syntax.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-string-invalid.js45
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string-err.js45
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string.js41
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-undefined.js54
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-distinct.js39
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-flags-defined.js46
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-immutable-lastindex.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-props.js75
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-same.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js44
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid.js46
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-u.js53
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string.js44
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-to-string-err.js44
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-undefined.js53
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-not-object.js44
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-obj-not-regexp.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/order-after-compile.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/prototype/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/RegExp/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/B.2.3.2.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/attr-tostring-err.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/anchor/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/B.2.3.3.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/not-a-constructor.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/big/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/B.2.3.4.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/blink/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/B.2.3.5.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/bold/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/B.2.3.6.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fixed/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/B.2.3.7.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/attr-tostring-err.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/B.2.3.8.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/attr-tostring-err.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/B.2.3.9.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/italics/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/B.2.3.10.js28
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/attr-tostring-err.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/link/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/match/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/match/custom-matcher-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/match/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/custom-matcher-emulates-undefined.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replace/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replace/custom-replacer-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replace/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/custom-replacer-emulates-undefined.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/search/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/search/custom-searcher-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/search/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/B.2.3.11.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/small/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/split/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/split/custom-splitter-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/split/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/B.2.3.12.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/strike/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/B.2.3.13.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/not-a-constructor.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sub/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/B.2.3.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-falsey.js39
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-negative.js33
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-positive.js38
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-to-int-err.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-undef.js36
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/not-a-constructor.js34
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-and-length-as-numbers.js94
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-negative.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-to-int-err.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/surrogate-pairs.js26
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-non-obj-coerce.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-to-str-err.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/B.2.3.14.js25
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/not-a-constructor.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/prop-desc.js20
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/sup/this-val-tostring-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/length.js33
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/name.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/prop-desc.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/reference-trimStart.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/length.js33
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/name.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/prop-desc.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/reference-trimEnd.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/String/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/iterator-method-emulates-undefined.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/shell.js124
-rw-r--r--js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/argument_bigint.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/argument_types.js35
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/empty-string.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/escape-above-astral.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/escape-above.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/escape-below.js56
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/not-a-constructor.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/prop-desc.js21
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/to-primitive-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/to-primitive-observe.js22
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/to-string-err-symbol.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/to-string-err.js21
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/to-string-observe.js54
-rw-r--r--js/src/tests/test262/annexB/built-ins/escape/unmodified.js23
-rw-r--r--js/src/tests/test262/annexB/built-ins/shell.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/argument_bigint.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/argument_types.js35
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/browser.js0
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/empty-string.js19
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/four-ignore-bad-u.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/four-ignore-end-str.js96
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/four-ignore-non-hex.js45
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/four.js75
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/length.js32
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/name.js29
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/not-a-constructor.js30
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/prop-desc.js21
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/shell.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/to-primitive-err.js24
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/to-primitive-observe.js22
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/to-string-err-symbol.js18
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/to-string-err.js21
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/to-string-observe.js54
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/two-ignore-end-str.js49
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/two-ignore-non-hex.js37
-rw-r--r--js/src/tests/test262/annexB/built-ins/unescape/two.js71
-rw-r--r--js/src/tests/test262/annexB/language/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/comments/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/comments/multi-line-html-close.js90
-rw-r--r--js/src/tests/test262/annexB/language/comments/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js39
-rw-r--r--js/src/tests/test262/annexB/language/comments/single-line-html-close-unicode-separators.js52
-rw-r--r--js/src/tests/test262/annexB/language/comments/single-line-html-close.js50
-rw-r--r--js/src/tests/test262/annexB/language/comments/single-line-html-open.js44
-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/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
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/dstr/array-pattern-emulates-undefined.js46
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/dstr/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/dstr/object-pattern-emulates-undefined.js37
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/dstr/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/assignment/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/coalesce/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/coalesce/emulates-undefined.js22
-rw-r--r--js/src/tests/test262/annexB/language/expressions/coalesce/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/conditional/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/conditional/emulates-undefined.js27
-rw-r--r--js/src/tests/test262/annexB/language/expressions/conditional/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/does-not-equals/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/does-not-equals/emulates-undefined.js34
-rw-r--r--js/src/tests/test262/annexB/language/expressions/does-not-equals/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/equals/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/equals/emulates-undefined.js32
-rw-r--r--js/src/tests/test262/annexB/language/expressions/equals/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-and/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-and/emulates-undefined.js26
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-and/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-assignment/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-and.js27
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-coalesce.js21
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-or.js28
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-assignment/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-not/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-not/emulates-undefined.js27
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-not/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-or/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-or/emulates-undefined.js26
-rw-r--r--js/src/tests/test262/annexB/language/expressions/logical-or/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-equals/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-equals/emulates-undefined.js29
-rw-r--r--js/src/tests/test262/annexB/language/expressions/strict-equals/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/template-literal/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-non-strict.js15
-rw-r--r--js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict-strict.js20
-rw-r--r--js/src/tests/test262/annexB/language/expressions/template-literal/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/typeof/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/typeof/emulates-undefined.js29
-rw-r--r--js/src/tests/test262/annexB/language/expressions/typeof/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/yield/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/yield/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/expressions/yield/star-iterable-return-emulates-undefined-throws-when-called.js33
-rw-r--r--js/src/tests/test262/annexB/language/expressions/yield/star-iterable-throw-emulates-undefined-throws-when-called.js50
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js30
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js51
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js46
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js46
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js20
-rw-r--r--js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js35
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js38
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js37
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js58
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js54
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js55
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js65
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js40
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js45
-rw-r--r--js/src/tests/test262/annexB/language/function-code/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js41
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js52
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js47
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js48
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js49
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js59
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js34
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js33
-rw-r--r--js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js35
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js24
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js53
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js43
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js42
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js57
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js58
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js31
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js40
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js39
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js54
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js50
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js61
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js38
-rw-r--r--js/src/tests/test262/annexB/language/global-code/shell.js14
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js34
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js32
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js47
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js37
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js26
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js36
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js51
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js52
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js25
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js34
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js33
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js48
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js44
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js45
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js46
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js55
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js27
-rw-r--r--js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js32
-rw-r--r--js/src/tests/test262/annexB/language/literals/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/class-escape.js72
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/extended-pattern-char.js32
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/identity-escape.js48
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/legacy-octal-escape.js72
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges-no-dash.js49
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges.js36
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-followed-by.js70
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-not-followed-by.js70
-rw-r--r--js/src/tests/test262/annexB/language/literals/regexp/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/literals/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/subclass/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/subclass/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/subclass/superclass-emulates-undefined.js35
-rw-r--r--js/src/tests/test262/annexB/language/statements/class/subclass/superclass-prototype-emulates-undefined.js31
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/dstr/array-pattern-emulates-undefined.js39
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/dstr/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/dstr/object-pattern-emulates-undefined.js37
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/dstr/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/const/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-await-of/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-await-of/iterator-close-return-emulates-undefined-throws-when-called.js40
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-await-of/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/bare-initializer.js16
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/const-initializer.js16
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/let-initializer.js16
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/nonstrict-initializer.js41
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/strict-initializer-strict.js17
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/var-arraybindingpattern-initializer.js15
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-in/var-objectbindingpattern-initializer.js16
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-of/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js27
-rw-r--r--js/src/tests/test262/annexB/language/statements/for-of/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/function/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/function/default-parameters-emulates-undefined.js74
-rw-r--r--js/src/tests/test262/annexB/language/statements/function/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/if/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/if/emulated-undefined.js33
-rw-r--r--js/src/tests/test262/annexB/language/statements/if/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/labeled/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/labeled/function-declaration.js14
-rw-r--r--js/src/tests/test262/annexB/language/statements/labeled/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/switch/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/switch/emulates-undefined.js33
-rw-r--r--js/src/tests/test262/annexB/language/statements/switch/shell.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/browser.js0
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-in-var.js29
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-of-var.js29
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-var.js29
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement-captured.js23
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement.js22
-rw-r--r--js/src/tests/test262/annexB/language/statements/try/shell.js0
-rw-r--r--js/src/tests/test262/annexB/shell.js0
1254 files changed, 44352 insertions, 0 deletions
diff --git a/js/src/tests/test262/annexB/browser.js b/js/src/tests/test262/annexB/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Array/browser.js b/js/src/tests/test262/annexB/built-ins/Array/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Array/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Array/from/browser.js b/js/src/tests/test262/annexB/built-ins/Array/from/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Array/from/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Array/from/iterator-method-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/Array/from/iterator-method-emulates-undefined.js
new file mode 100644
index 0000000000..5ee69df755
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Array/from/iterator-method-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.from
+description: >
+ [[IsHTMLDDA]] object as @@iterator method gets called.
+info: |
+ Array.from ( items [ , mapfn [ , thisArg ] ] )
+
+ [...]
+ 4. Let usingIterator be ? GetMethod(items, @@iterator).
+ 5. If usingIterator is not undefined, then
+ [...]
+ c. Let iteratorRecord be ? GetIterator(items, sync, usingIterator).
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ [...]
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+features: [Symbol.iterator, IsHTMLDDA]
+---*/
+
+var items = {};
+items[Symbol.iterator] = $262.IsHTMLDDA;
+
+assert.throws(TypeError, function() {
+ Array.from(items);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Array/from/shell.js b/js/src/tests/test262/annexB/built-ins/Array/from/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Array/from/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Array/shell.js b/js/src/tests/test262/annexB/built-ins/Array/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Array/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/browser.js b/js/src/tests/test262/annexB/built-ins/Date/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/browser.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/B.2.4.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/B.2.4.js
new file mode 100644
index 0000000000..4e6091dd06
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/B.2.4.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.4
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (Date.prototype.getYear)
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype, "getYear", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/browser.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/length.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/length.js
new file mode 100644
index 0000000000..72bb65b0e7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.4.1
+description: >
+ Date.prototype.getYear.length is 0.
+info: |
+ Date.prototype.getYear ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype.getYear, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/name.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/name.js
new file mode 100644
index 0000000000..6a3db43a9f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.4.1
+description: >
+ Date.prototype.getYear.name is "getYear".
+info: |
+ Date.prototype.getYear ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype.getYear, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "getYear"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/nan.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/nan.js
new file mode 100644
index 0000000000..121c54fcd5
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/nan.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.getyear
+es6id: B.2.4.1
+es5id: B.2.4
+description: NaN time value
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+ 2. If t is NaN, return NaN.
+---*/
+
+var date = new Date({});
+
+assert.sameValue(date.getYear(), NaN);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/not-a-constructor.js
new file mode 100644
index 0000000000..a3936a335e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Date.prototype.getYear does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Date.prototype.getYear),
+ false,
+ 'isConstructor(Date.prototype.getYear) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let date = new Date(Date.now()); new date.getYear();
+}, '`let date = new Date(Date.now()); new date.getYear()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/return-value.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/return-value.js
new file mode 100644
index 0000000000..1df44ae303
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/return-value.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.getyear
+es6id: B.2.4.1
+es5id: B.2.4
+description: >
+ Return value for objects with numeric value in [[DateValue]] internal slot
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+ 2. If t is NaN, return NaN.
+ 3. Return YearFromTime(LocalTime(t)) - 1900.
+---*/
+
+assert.sameValue(new Date(1899, 0).getYear(), -1, '1899: first millisecond');
+assert.sameValue(
+ new Date(1899, 11, 31, 23, 59, 59, 999).getYear(),
+ -1,
+ '1899: final millisecond'
+);
+
+assert.sameValue(new Date(1900, 0).getYear(), 0, '1900: first millisecond');
+assert.sameValue(
+ new Date(1900, 11, 31, 23, 59, 59, 999).getYear(),
+ 0,
+ '1900: final millisecond'
+);
+
+assert.sameValue(new Date(1970, 0).getYear(), 70, '1970: first millisecond');
+assert.sameValue(
+ new Date(1970, 11, 31, 23, 59, 59, 999).getYear(),
+ 70,
+ '1970: final millisecond'
+);
+
+assert.sameValue(new Date(2000, 0).getYear(), 100, '2000: first millisecond');
+assert.sameValue(
+ new Date(2000, 11, 31, 23, 59, 59, 999).getYear(),
+ 100,
+ '2000: final millisecond'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/shell.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/this-not-date.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/this-not-date.js
new file mode 100644
index 0000000000..cb6888f80a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/getYear/this-not-date.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.getyear
+es6id: B.2.4.1
+es5id: B.2.4
+description: Behavior when `this` value has no [[DateValue]] internal slot
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+---*/
+
+var getYear = Date.prototype.getYear;
+
+assert.sameValue(typeof getYear, 'function');
+
+assert.throws(TypeError, function() {
+ getYear.call({});
+}, 'object');
+
+assert.throws(TypeError, function() {
+ getYear.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ getYear.call(null);
+}, 'null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/B.2.5.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/B.2.5.js
new file mode 100644
index 0000000000..91eb6f7451
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/B.2.5.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.5
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (Date.prototype.setYear)
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype, "setYear", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/browser.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/length.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/length.js
new file mode 100644
index 0000000000..946c22d3d1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.4.2
+description: >
+ Date.prototype.setYear.length is 1.
+info: |
+ Date.prototype.setYear ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype.setYear, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/name.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/name.js
new file mode 100644
index 0000000000..f35e39d327
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.4.2
+description: >
+ Date.prototype.setYear.name is "setYear".
+info: |
+ Date.prototype.setYear ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Date.prototype.setYear, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "setYear"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/not-a-constructor.js
new file mode 100644
index 0000000000..906214fde4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Date.prototype.setYear does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Date.prototype.setYear),
+ false,
+ 'isConstructor(Date.prototype.setYear) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let date = new Date(Date.now()); new date.setYear();
+}, '`let date = new Date(Date.now()); new date.setYear()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/shell.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-not-date.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-not-date.js
new file mode 100644
index 0000000000..15614f98e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-not-date.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: Behavior when "this" value has no [[DateValue]] internal slot
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+---*/
+
+var setYear = Date.prototype.setYear;
+
+assert.sameValue(typeof setYear, 'function');
+
+assert.throws(TypeError, function() {
+ setYear.call({}, 1);
+}, 'object');
+
+assert.throws(TypeError, function() {
+ setYear.call(undefined, 1);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ setYear.call(null, 1);
+}, 'null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-nan.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-nan.js
new file mode 100644
index 0000000000..fb99ad3765
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-nan.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: >
+ Behavior when the [[DateValue]] internal slot of "this" value is NaN
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+ 2. If t is NaN, let t be +0; otherwise, let t be LocalTime(t).
+---*/
+
+var date = new Date({});
+var expected = new Date(1971, 0).valueOf();
+
+assert.sameValue(date.setYear(71), expected, 'method return value');
+assert.sameValue(date.valueOf(), expected, '[[DateValue]] internal slot');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-valid.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-valid.js
new file mode 100644
index 0000000000..35ccee0fbf
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/this-time-valid.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: >
+ Behavior when the [[DateValue]] internal slot of "this" value is an integer
+ value
+info: |
+ 1. Let t be ? thisTimeValue(this value).
+ 2. If t is NaN, let t be +0; otherwise, let t be LocalTime(t).
+---*/
+
+var date = new Date(1970, 1, 2, 3, 4, 5);
+var expected = new Date(1971, 1, 2, 3, 4, 5).valueOf();
+
+assert.sameValue(date.setYear(71), expected, 'method return value');
+assert.sameValue(date.valueOf(), expected, '[[DateValue]] internal slot');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/time-clip.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/time-clip.js
new file mode 100644
index 0000000000..f296e204ab
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/time-clip.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: Clipping of new time value
+info: |
+ [...]
+ 9. Set the [[DateValue]] internal slot of this Date object to
+ TimeClip(date).
+ 10. Return the value of the [[DateValue]] internal slot of this Date
+ object.
+---*/
+
+var date;
+
+date = new Date(1970, 8, 10, 0, 0, 0, 0);
+
+assert.notSameValue(
+ date.setYear(275760), NaN, 'method return value (valid date)'
+);
+assert.notSameValue(
+ date.valueOf(), NaN, '[[DateValue]] internal slot (valid date)'
+);
+
+date = new Date(1970, 8, 14, 0, 0, 0, 0);
+
+assert.sameValue(
+ date.setYear(275760), NaN, 'method return value (invalid date)'
+);
+assert.sameValue(
+ date.valueOf(), NaN, '[[DateValue]] internal slot (invalid date)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-nan.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-nan.js
new file mode 100644
index 0000000000..9a14f8f777
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-nan.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: Behavior when year value coerces to NaN
+info: |
+ [...]
+ 3. Let y be ? ToNumber(year).
+ 4. If y is NaN, set the [[DateValue]] internal slot of this Date object to
+ NaN and return NaN.
+features: [Symbol]
+---*/
+
+var date;
+
+date = new Date();
+assert.sameValue(date.setYear(), NaN, 'return value (no argument)');
+assert.sameValue(
+ date.valueOf(), NaN, '[[DateValue]] internal slot (no argument)'
+);
+
+date = new Date();
+assert.sameValue(date.setYear(NaN), NaN, 'return value (literal NaN)');
+assert.sameValue(
+ date.valueOf(), NaN, '[[DateValue]] internal slot (literal NaN)'
+);
+
+date = new Date();
+assert.sameValue(
+ date.setYear('not a number'), NaN, 'return value (NaN from ToNumber)'
+);
+assert.sameValue(
+ date.valueOf(), NaN, '[[DateValue]] internal slot (NaN from ToNumber)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-absolute.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-absolute.js
new file mode 100644
index 0000000000..61cc1d91a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-absolute.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: >
+ Behavior when the integer representation of the specified `year` is not
+ relative to 1900
+info: |
+ [...]
+ 5. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yyyy be ToInteger(y) +
+ 1900.
+ 6. Else, let yyyy be y.
+ [...]
+---*/
+
+var date;
+
+date = new Date(1970, 0);
+date.setYear(-1);
+assert.sameValue(date.getFullYear(), -1);
+
+date = new Date(1970, 0);
+date.setYear(100);
+assert.sameValue(date.getFullYear(), 100);
+
+date = new Date(1970, 0);
+date.setYear(1899);
+assert.sameValue(date.getFullYear(), 1899);
+
+date = new Date(1970, 0);
+date.setYear(1900);
+assert.sameValue(date.getFullYear(), 1900);
+
+date = new Date(1970, 0);
+date.setYear(1999);
+assert.sameValue(date.getFullYear(), 1999);
+
+date = new Date(1970, 0);
+date.setYear(2000);
+assert.sameValue(date.getFullYear(), 2000);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-relative.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-relative.js
new file mode 100644
index 0000000000..632acfa129
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-number-relative.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: >
+ Behavior when the integer representation of the specified `year` is
+ relative to 1900
+info: |
+ [...]
+ 5. If y is not NaN and 0 ≤ ToInteger(y) ≤ 99, let yyyy be ToInteger(y) +
+ 1900.
+ [...]
+---*/
+
+var date;
+
+date = new Date(1970, 0);
+date.setYear(-0.9999999);
+assert.sameValue(date.getFullYear(), 1900, 'y = -0.999999');
+
+date = new Date(1970, 0);
+date.setYear(-0);
+assert.sameValue(date.getFullYear(), 1900, 'y = -0');
+
+date = new Date(1970, 0);
+date.setYear(0);
+assert.sameValue(date.getFullYear(), 1900, 'y = 0');
+
+date = new Date(1970, 0);
+date.setYear(50);
+assert.sameValue(date.getFullYear(), 1950, 'y = 50');
+
+date = new Date(1970, 0);
+date.setYear(50.999999);
+assert.sameValue(date.getFullYear(), 1950, 'y = 50.999999');
+
+date = new Date(1970, 0);
+date.setYear(99);
+assert.sameValue(date.getFullYear(), 1999, 'y = 99');
+
+date = new Date(1970, 0);
+date.setYear(99.999999);
+assert.sameValue(date.getFullYear(), 1999, 'y = 99.999999');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-to-number-err.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-to-number-err.js
new file mode 100644
index 0000000000..d7e318f571
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/setYear/year-to-number-err.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.setyear
+es6id: B.2.4.2
+es5id: B.2.5
+description: >
+ Behavior when calling ToNumber on year value returns an abrupt completion
+info: |
+ [...]
+ 3. Let y be ? ToNumber(year).
+features: [Symbol]
+---*/
+
+var date = new Date();
+var symbol = Symbol('');
+var year = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ date.setYear(year);
+});
+
+assert.throws(TypeError, function() {
+ date.setYear(symbol);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/shell.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/browser.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/not-a-constructor.js
new file mode 100644
index 0000000000..bb6c5f412f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Date.prototype.toGMTString does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Date.prototype.toGMTString),
+ false,
+ 'isConstructor(Date.prototype.toGMTString) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let date = new Date(Date.now()); new date.toGMTString();
+}, '`let date = new Date(Date.now()); new date.toGMTString()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/prop-desc.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/prop-desc.js
new file mode 100644
index 0000000000..c7f55f91a1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/prop-desc.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.6
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (Date.prototype.toGMTString)
+includes: [propertyHelper.js]
+
+---*/
+
+verifyProperty(Date.prototype, "toGMTString", {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/shell.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/value.js b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/value.js
new file mode 100644
index 0000000000..27e9f98edd
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/prototype/toGMTString/value.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.prototype.togmtstring
+es6id: B.2.4.3
+es5id: B.2.6
+description: Value of `Date.prototype.toGMTString`
+info: |
+ The function object that is the initial value of Date.prototype.toGMTString
+ is the same function object that is the initial value of
+ Date.prototype.toUTCString.
+---*/
+
+assert.sameValue(Date.prototype.toGMTString, Date.prototype.toUTCString);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Date/shell.js b/js/src/tests/test262/annexB/built-ins/Date/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Date/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Function/browser.js b/js/src/tests/test262/annexB/built-ins/Function/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-body.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-body.js
new file mode 100644
index 0000000000..49a409b8a6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-body.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Create a Function with the function body being a html close comment.
+info: |
+ 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ 7. If kind is "normal", then
+ a. Let goal be the grammar symbol FunctionBody[~Yield, ~Await].
+ ...
+ 11. Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text
+ as described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if
+ the parse fails.
+ ...
+---*/
+
+Function("\n-->");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-params.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-params.js
new file mode 100644
index 0000000000..c97834d6f4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-close-comment-params.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Create a Function with the function parameters being a html close comment.
+info: |
+ 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ 7. If kind is "normal", then
+ ...
+ b. Let parameterGoal be the grammar symbol FormalParameters[~Yield, ~Await].
+ ...
+ 10. Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text
+ as described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError
+ exception if the parse fails.
+ ...
+---*/
+
+Function("\n-->", "");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-body.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-body.js
new file mode 100644
index 0000000000..3dc973128b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-body.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Create a Function with the function body being a html open comment.
+info: |
+ 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ 7. If kind is "normal", then
+ a. Let goal be the grammar symbol FunctionBody[~Yield, ~Await].
+ ...
+ 11. Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text
+ as described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if
+ the parse fails.
+ ...
+---*/
+
+Function("<!--");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-params.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-params.js
new file mode 100644
index 0000000000..ea22bf96b6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-html-open-comment-params.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Create a Function with the function parameters being a html open comment.
+info: |
+ 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ 7. If kind is "normal", then
+ ...
+ b. Let parameterGoal be the grammar symbol FormalParameters[~Yield, ~Await].
+ ...
+ 10. Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text
+ as described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError
+ exception if the parse fails.
+ ...
+---*/
+
+Function("<!--", "");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js
new file mode 100644
index 0000000000..36e6a5bb25
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Function body is wrapped with new lines before being parsed
+info: |
+ The HTMLCloseComment requires a preceding line terminator.
+
+ Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ Set bodyText to ? ToString(bodyText).
+ Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text as
+ described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError exception if the
+ parse fails.
+ Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text as
+ described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if the parse
+ fails.
+---*/
+
+Function("-->");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-params.js b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-params.js
new file mode 100644
index 0000000000..73fea90809
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-params.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: >
+ Function parses the parameters text before forming the sourceText with the proper line feed.
+info: |
+ The HTMLCloseComment requires a preceding line terminator.
+
+ Runtime Semantics: CreateDynamicFunction(constructor, newTarget, kind, args)
+ ...
+ 16. Set bodyText to ? ToString(bodyText).
+ 17. Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text as
+ described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError exception if the
+ parse fails.
+ 18. Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text as
+ described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if the parse
+ fails.
+ ...
+ 41. Let sourceText be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED),
+ ") {", 0x000A (LINE FEED), bodyText, 0x000A (LINE FEED), and "}".
+---*/
+
+assert.throws(SyntaxError, () => Function("-->", ""));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Function/shell.js b/js/src/tests/test262/annexB/built-ins/Function/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Function/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Object/browser.js b/js/src/tests/test262/annexB/built-ins/Object/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Object/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Object/is/browser.js b/js/src/tests/test262/annexB/built-ins/Object/is/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Object/is/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/Object/is/emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/Object/is/emulates-undefined.js
new file mode 100644
index 0000000000..c6b4bb8417
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Object/is/emulates-undefined.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-object.is
+description: >
+ SameValue abstract op doesn't special-case [[IsHTMLDDA]] objects.
+info: |
+ Object.is ( value1, value2 )
+
+ 1. Return SameValue(value1, value2).
+
+ SameValue ( x, y )
+
+ 1. If Type(x) is different from Type(y), return false.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(Object.is(IsHTMLDDA, undefined), false, "SameValue with `undefined`");
+assert.sameValue(Object.is(undefined, IsHTMLDDA), false, "SameValue with `undefined`");
+
+assert.sameValue(Object.is(IsHTMLDDA, null), false, "SameValue with `null`");
+assert.sameValue(Object.is(null, IsHTMLDDA), false, "SameValue with `null`");
+
+assert(Object.is(IsHTMLDDA, IsHTMLDDA));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/Object/is/shell.js b/js/src/tests/test262/annexB/built-ins/Object/is/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Object/is/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/Object/shell.js b/js/src/tests/test262/annexB/built-ins/Object/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/Object/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-control-escape-russian-letter.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-control-escape-russian-letter.js
new file mode 100644
index 0000000000..b7caeb42a5
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-control-escape-russian-letter.js
@@ -0,0 +1,55 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: "CharacterEscape :: c ControlLetter"
+es5id: 15.10.2.10_A2.1_T3
+es6id: B.1.4
+description: >
+ "ControlLetter :: RUSSIAN ALPHABET is incorrect"
+ Instead, fall back to semantics to match literal "\\c"
+features: [generators]
+---*/
+
+function* invalidControls() {
+ // Check upper case Cyrillic
+ for (var alpha = 0x0410; alpha <= 0x042F; alpha++) {
+ yield String.fromCharCode(alpha);
+ }
+
+ // Check lower case Cyrillic
+ for (alpha = 0x0430; alpha <= 0x044F; alpha++) {
+ yield String.fromCharCode(alpha);
+ }
+
+ // Check ASCII characters which are not in the extended range or syntax
+ // characters
+ for (alpha = 0x00; alpha <= 0x7F; alpha++) {
+ let letter = String.fromCharCode(alpha);
+ if (!letter.match(/[0-9A-Za-z_\$(|)\[\]\/\\^]/)) {
+ yield letter;
+ }
+ }
+
+ // Check for end of string
+ yield "";
+}
+
+for (let letter of invalidControls()) {
+ var source = "\\c" + letter;
+ var re = new RegExp(source);
+
+ if (letter.length > 0) {
+ var char = letter.charCodeAt(0);
+ var str = String.fromCharCode(char % 32);
+ var arr = re.exec(str);
+ assert.sameValue(arr, null, `Character ${letter} unreasonably wrapped around as a control character`);
+ }
+ arr = re.exec(source.substring(1));
+ assert.sameValue(arr, null, `invalid \\c escape matched c rather than \\c when followed by ${letter}`);
+
+ arr = re.exec(source);
+ assert.notSameValue(arr, null, `invalid \\c escape failed to match \\c when followed by ${letter}`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-class-range.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-class-range.js
new file mode 100644
index 0000000000..4d49de4ea4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-class-range.js
@@ -0,0 +1,31 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production CharacterClass :: [ [lookahead \notin {^}] ClassRanges ]
+ evaluates by evaluating ClassRanges to obtain a CharSet and returning
+ that CharSet and the boolean false
+es5id: 15.10.2.13_A1_T16
+es6id: B.1.4
+description: >
+ Execute /[\d][\12-\14]{1,}[^\d]/.exec("line1\n\n\n\n\nline2") and
+ check results
+---*/
+
+var __executed = /[\d][\12-\14]{1,}[^\d]/.exec("line1\n\n\n\n\nline2");
+
+var __expected = ["1\n\n\n\n\nl"];
+__expected.index = 4;
+__expected.input = "line1\n\n\n\n\nline2";
+
+assert.sameValue(__executed.length, __expected.length, '.length');
+assert.sameValue(__executed.index, __expected.index, '.index');
+assert.sameValue(__executed.input, __expected.input, '.input');
+
+//CHECK#4
+for(var index=0; index < __expected.length; index++) {
+ assert.sameValue(__executed[index], __expected[index], 'index: ' + index);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-not-capturing.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-not-capturing.js
new file mode 100644
index 0000000000..cd0bf7ed7e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-decimal-escape-not-capturing.js
@@ -0,0 +1,20 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ An escape sequence of the form \ followed by a nonzero decimal number n
+ matches the result of the nth set of capturing parentheses (see
+ 15.10.2.11)
+es5id: 15.10.2.9_A1_T4
+es6id: B.1.4
+description: >
+ Execute /\b(\w+) \2\b/.test("do you listen the the band") and
+ check results
+---*/
+
+var executed = /\b(\w+) \2\b/.test("do you listen the the band");
+
+assert.sameValue(executed, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class-range.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class-range.js
new file mode 100644
index 0000000000..011790acdf
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class-range.js
@@ -0,0 +1,26 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: prod-annexB-ClassAtomNoDash
+description: >
+ Invalid \c in a range behaves like [\\c-_]
+info: |
+ ClassAtomNoDash :: `\`
+
+ The production ClassAtomNoDash :: `\` evaluates as follows:
+ 1. Return the CharSet containing the single character `\`.
+---*/
+
+let re = /[\\c-f]/
+
+assert(re.test("\\"))
+assert(!re.test("b"))
+assert(re.test("c"))
+assert(re.test("d"))
+assert(re.test("e"))
+assert(re.test("f"))
+assert(!re.test("g"))
+assert(!re.test("-"))
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class.js
new file mode 100644
index 0000000000..0e9451e537
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-invalid-control-escape-character-class.js
@@ -0,0 +1,56 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: prod-annexB-ClassAtomNoDash
+description: >
+ Character classes containing an invalid control escape behave like [\\c]
+info: |
+ ClassAtomNoDash :: `\`
+
+ The production ClassAtomNoDash :: `\` evaluates as follows:
+ 1. Return the CharSet containing the single character `\`.
+features: [generators]
+---*/
+
+function* invalidControls() {
+ // Check ASCII characters which are not in the extended range or syntax
+ // characters
+ for (let alpha = 0x00; alpha <= 0x7F; alpha++) {
+ let letter = String.fromCharCode(alpha);
+ if (!letter.match(/[0-9A-Za-z_\$(|)\[\]\/\\^]/)) {
+ yield letter;
+ }
+ }
+ yield "";
+}
+
+for (let letter of invalidControls()) {
+ var source = "[\\c" + letter + "]";
+ var re = new RegExp(source);
+
+ if (letter.length > 0) {
+ var char = letter.charCodeAt(0);
+ var str = String.fromCharCode(char % 32);
+ var arr = re.exec(str);
+ if (str !== letter && arr !== null) {
+ throw new Test262Error(`Character ${letter} unreasonably wrapped around as a control character`);
+ }
+
+ arr = re.exec(letter);
+ if (arr === null) {
+ throw new Test262Error(`Character ${letter} missing from character class ${source}`);
+ }
+ }
+ arr = re.exec("\\")
+ if (arr === null) {
+ throw new Test262Error(`Character \\ missing from character class ${source}`);
+ }
+ arr = re.exec("c")
+ if (arr === null) {
+ throw new Test262Error(`Character c missing from character class ${source}`);
+ }
+}
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js
new file mode 100644
index 0000000000..011e7aeac6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js
@@ -0,0 +1,31 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ RegularExpressionFirstChar :: BackslashSequence :: \NonTerminator,
+ RegularExpressionChars :: [empty], RegularExpressionFlags :: [empty]
+es5id: 7.8.5_A1.4_T2
+es6id: 11.8.5
+description: Complex test with eval, using syntax pattern
+---*/
+
+for (var cu = 0; cu <= 0xffff; ++cu) {
+ var Elimination =
+ ((cu === 0x002A) || (cu === 0x002F) || (cu === 0x005C) || (cu === 0x002B) ||
+ (cu === 0x003F) || (cu === 0x0028) || (cu === 0x0029) ||
+ (cu === 0x005B) || (cu === 0x005D) || (cu === 0x007B) || (cu === 0x007D));
+ /*
+ * \u002A / \u002F \ \u005C + \u002B
+ ? \u003F ( \u0028 ) \u0029
+ [ \u005B ] \u005D { \u007B } \u007D
+ */
+ var LineTerminator = ((cu === 0x000A) || (cu === 0x000D) || (cu === 0x2028) || (cu === 0x2029));
+ if ((Elimination || LineTerminator ) === false) {
+ var xx = "\\" + String.fromCharCode(cu);
+ var pattern = eval("/" + xx + "/");
+ assert.sameValue(pattern.source, xx, "Code unit: " + cu.toString(16));
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape.js
new file mode 100644
index 0000000000..4b6c50fb00
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-leading-escape.js
@@ -0,0 +1,16 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ RegularExpressionFirstChar :: BackslashSequence :: \NonTerminator,
+ RegularExpressionChars :: [empty], RegularExpressionFlags :: [empty]
+es5id: 7.8.5_A1.4_T1
+es6id: 11.8.5
+description: Check similar to (/\1/.source === "\\1")
+---*/
+
+assert.sameValue(/\1/.source, "\\1");
+assert.sameValue(/\a/.source, "\\a");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js
new file mode 100644
index 0000000000..76ad15761d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js
@@ -0,0 +1,31 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ RegularExpressionChar :: BackslashSequence :: \NonTerminator,
+ RegularExpressionFlags :: [empty]
+es5id: 7.8.5_A2.4_T2
+es6id: 11.8.5
+description: Complex test with eval, using syntax pattern
+---*/
+
+for (var cu = 0; cu <= 0xffff; ++cu) {
+ var Elimination =
+ ((cu === 0x002A) || (cu === 0x002F) || (cu === 0x005C) || (cu === 0x002B) ||
+ (cu === 0x003F) || (cu === 0x0028) || (cu === 0x0029) ||
+ (cu === 0x005B) || (cu === 0x005D) || (cu === 0x007B) || (cu === 0x007D));
+ /*
+ * \u002A / \u002F \ \u005C + \u002B
+ ? \u003F ( \u0028 ) \u0029
+ [ \u005B ] \u005D { \u007B } \u007D
+ */
+ var LineTerminator = ((cu === 0x000A) || (cu === 0x000D) || (cu === 0x2028) || (cu === 0x2029));
+ if ((Elimination || LineTerminator ) === false) {
+ var xx = "a\\" + String.fromCharCode(cu);
+ var pattern = eval("/" + xx + "/");
+ assert.sameValue(pattern.source, xx, "Code unit: " + cu.toString(16));
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape.js b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape.js
new file mode 100644
index 0000000000..9af5e0ccf9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/RegExp-trailing-escape.js
@@ -0,0 +1,16 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ RegularExpressionChar :: BackslashSequence :: \NonTerminator,
+ RegularExpressionFlags :: [empty]
+es5id: 7.8.5_A2.4_T1
+es6id: 11.8.5
+description: Check similar to (/a\1/.source === "a\\1")
+---*/
+
+assert.sameValue(/a\1/.source, "a\\1");
+assert.sameValue(/a\a/.source, "a\\a");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/incomplete_hex_unicode_escape.js b/js/src/tests/test262/annexB/built-ins/RegExp/incomplete_hex_unicode_escape.js
new file mode 100644
index 0000000000..915c303f3f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/incomplete_hex_unicode_escape.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 Zirak. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: An incomplete HexEscape or UnicodeEscape should be treated as an Identity Escape
+info: |
+ An incomplete HexEscape (e.g. /\x/) or UnicodeEscape (/\u/) should fall
+ through to IdentityEscape
+esid: prod-AtomEscape
+---*/
+
+// Hex escape
+assert(/\x/.test("x"), "/\\x/");
+assert(/\xa/.test("xa"), "/\\xa/");
+
+// Unicode escape
+assert(/\u/.test("u"), "/\\u/");
+assert(/\ua/.test("ua"), "/\\ua/");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js
new file mode 100644
index 0000000000..7f11026dbc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/prop-desc.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.$1-$9
+info: |
+ RegExp.$1-$9 are accessor properties with attributes
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ [[Set]]: undefined,
+ }
+
+ get RegExp.$1-$9
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+for (let i = 1; i <= 9; i++) {
+ const property = "$" + i;
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ assert.sameValue(desc.set, undefined, property + " setter");
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ verifyProperty(RegExp, property, {
+ enumerable: false,
+ configurable: true
+ });
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..885e64fcc0
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-cross-realm-constructor.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.$1-$9 throw a TypeError for cross-realm receiver
+info: |
+ get RegExp.$1-$9
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect]
+---*/
+
+const other = $262.createRealm().global;
+
+for (let i = 1; i <= 9; i++) {
+ const property = "$" + i;
+ assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, property, other.RegExp);
+ },
+ "RegExp." + property + " getter throws for cross-realm receiver"
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..5afd16c0fb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-not-regexp-constructor.js
@@ -0,0 +1,63 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.$1-$9 throw a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.$1-$9
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+for (let i = 1; i <= 9; i++) {
+ const property = "$" + i;
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get();
+ },
+ "RegExp." + property + " getter throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(/ /);
+ },
+ "RegExp." + property + " getter throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(RegExp.prototype);
+ },
+ "RegExp." + property + " getter throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(value);
+ },
+ "RegExp." + property + ' getter throws for primitive "' + value + '" receiver'
+ );
+ });
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js
new file mode 100644
index 0000000000..99970a8332
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/index/this-subclass-constructor.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.$1-$9 throw a TypeError for subclass receiver
+info: |
+ get RegExp.$1-$9
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpParen1-9]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+for (let i = 1; i <= 9; i++) {
+ const property = "$" + i;
+ assert.throws(
+ TypeError,
+ function () {
+ MyRegExp[property];
+ },
+ "RegExp." + property + " getter throws for subclass receiver"
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js
new file mode 100644
index 0000000000..e5f0c85603
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/prop-desc.js
@@ -0,0 +1,45 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.input
+info: |
+ RegExp.input is an accessor property with attributes:
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ }
+
+ get RegExp.input
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]).
+
+ set RegExp.input = val
+
+ 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(RegExp, "input");
+
+assert.sameValue(typeof desc.get, "function", "`get` property");
+assert.sameValue(typeof desc.set, "function", "`set` property");
+
+verifyProperty(RegExp, "input", {
+ enumerable: false,
+ configurable: true
+});
+
+desc = Object.getOwnPropertyDescriptor(RegExp, "$_");
+
+assert.sameValue(typeof desc.get, "function", "`get` property");
+assert.sameValue(typeof desc.set, "function", "`set` property");
+
+verifyProperty(RegExp, "$_", {
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..a7f0446619
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-cross-realm-constructor.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.input throws a TypeError for cross-realm receiver
+info: |
+ get RegExp.input
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]).
+
+ set RegExp.input = val
+
+ 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+
+ SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect,Reflect.set]
+---*/
+
+const other = $262.createRealm().global;
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "input", other.RegExp);
+ },
+ "RegExp.input getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.set(RegExp, "input", "", other.RegExp);
+ },
+ "RegExp.input setter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "$_", other.RegExp);
+ },
+ "RegExp.$_ getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.set(RegExp, "$_", "", other.RegExp);
+ },
+ "RegExp.$_ setter throws for cross-realm receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..4a8a7ff3c6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-not-regexp-constructor.js
@@ -0,0 +1,76 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.input throws a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.input
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]).
+
+ set RegExp.input = val
+
+ 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+
+ SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+["input", "$_"].forEach(function (property) {
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ ["get", "set"].forEach(function (accessor) {
+ const messagePrefix = "RegExp." + property + " " + accessor + "ter";
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc[accessor], "function", messagePrefix);
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc[accessor]();
+ },
+ messagePrefix + " throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc[accessor].call(/ /);
+ },
+ messagePrefix + " throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc[accessor].call(RegExp.prototype);
+ },
+ messagePrefix + " throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc[accessor].call(value);
+ },
+ messagePrefix + ' throws for primitive "' + value + '" receiver'
+ );
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js
new file mode 100644
index 0000000000..beb7c8c66d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/input/this-subclass-constructor.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.input throws a TypeError for subclass receiver
+info: |
+ get RegExp.input
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]]).
+
+ set RegExp.input = val
+
+ 1. Return ? SetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpInput]], val).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+
+ SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.input;
+ },
+ "RegExp.input getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.input = "";
+ },
+ "RegExp.input setter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.$_;
+ },
+ "RegExp.$_ getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.$_ = "";
+ },
+ "RegExp.$_ setter throws for subclass receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js
new file mode 100644
index 0000000000..62854362c5
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/prop-desc.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.lastMatch
+info: |
+ RegExp.lastMatch is an accessor property with attributes:
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ [[Set]]: undefined,
+ }
+
+ get RegExp.lastMatch
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(RegExp, "lastMatch");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "lastMatch", {
+ enumerable: false,
+ configurable: true
+});
+
+desc = Object.getOwnPropertyDescriptor(RegExp, "$&");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "$&", {
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..c9b7c97abc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-cross-realm-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastMatch throws a TypeError for cross-realm receiver
+info: |
+ get RegExp.lastMatch
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect]
+---*/
+
+const other = $262.createRealm().global;
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "lastMatch", other.RegExp);
+ },
+ "RegExp.lastMatch getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "$&", other.RegExp);
+ },
+ "RegExp.$& getter throws for cross-realm receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..35ad7711f6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-not-regexp-constructor.js
@@ -0,0 +1,62 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastMatch throws a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.lastMatch
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+["lastMatch", "$&"].forEach(function (property) {
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get();
+ },
+ "RegExp." + property + " getter throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(/ /);
+ },
+ "RegExp." + property + " getter throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(RegExp.prototype);
+ },
+ "RegExp." + property + " getter throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(value);
+ },
+ "RegExp." + property + ' getter throws for primitive "' + value + '" receiver'
+ );
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js
new file mode 100644
index 0000000000..510697fd06
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastMatch/this-subclass-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastMatch throws a TypeError for subclass receiver
+info: |
+ get RegExp.lastMatch
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastMatch]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.lastMatch;
+ },
+ "RegExp.lastMatch getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp["$&"];
+ },
+ "RegExp.$& getter throws for subclass receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js
new file mode 100644
index 0000000000..cc8c0adc10
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/prop-desc.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.lastParen
+info: |
+ RegExp.lastParen is an accessor property with attributes:
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ [[Set]]: undefined,
+ }
+
+ get RegExp.lastParen
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(RegExp, "lastParen");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "lastParen", {
+ enumerable: false,
+ configurable: true
+});
+
+desc = Object.getOwnPropertyDescriptor(RegExp, "$+");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "$+", {
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..39b723d8d9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-cross-realm-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastParen throws a TypeError for cross-realm receiver
+info: |
+ get RegExp.lastParen
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect]
+---*/
+
+const other = $262.createRealm().global;
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "lastParen", other.RegExp);
+ },
+ "RegExp.lastParen getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "$+", other.RegExp);
+ },
+ "RegExp.$+ getter throws for cross-realm receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..bd36699732
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-not-regexp-constructor.js
@@ -0,0 +1,62 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastParen throws a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.lastParen
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+["lastParen", "$+"].forEach(function (property) {
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get();
+ },
+ "RegExp." + property + " getter throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(/ /);
+ },
+ "RegExp." + property + " getter throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(RegExp.prototype);
+ },
+ "RegExp." + property + " getter throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(value);
+ },
+ "RegExp." + property + ' getter throws for primitive "' + value + '" receiver'
+ );
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js
new file mode 100644
index 0000000000..36fdf2cd3c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/lastParen/this-subclass-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.lastParen throws a TypeError for subclass receiver
+info: |
+ get RegExp.lastParen
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLastParen]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.lastParen;
+ },
+ "RegExp.lastParen getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp["$+"];
+ },
+ "RegExp.$+ getter throws for subclass receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js
new file mode 100644
index 0000000000..7504bdab79
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/prop-desc.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.leftContext
+info: |
+ RegExp.leftContext is an accessor property with attributes:
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ [[Set]]: undefined,
+ }
+
+ get RegExp.leftContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(RegExp, "leftContext");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "leftContext", {
+ enumerable: false,
+ configurable: true
+});
+
+desc = Object.getOwnPropertyDescriptor(RegExp, "$`");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "$`", {
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..ba4d23f90e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-cross-realm-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.leftContext throws a TypeError for cross-realm receiver
+info: |
+ get RegExp.leftContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect]
+---*/
+
+const other = $262.createRealm().global;
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "leftContext", other.RegExp);
+ },
+ "RegExp.leftContext getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "$`", other.RegExp);
+ },
+ "RegExp.$` getter throws for cross-realm receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..a25bd49cad
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-not-regexp-constructor.js
@@ -0,0 +1,62 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.leftContext throws a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.leftContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+["leftContext", "$`"].forEach(function (property) {
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get();
+ },
+ "RegExp." + property + " getter throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(/ /);
+ },
+ "RegExp." + property + " getter throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(RegExp.prototype);
+ },
+ "RegExp." + property + " getter throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(value);
+ },
+ "RegExp." + property + ' getter throws for primitive "' + value + '" receiver'
+ );
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js
new file mode 100644
index 0000000000..7eba961283
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/leftContext/this-subclass-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.leftContext throws a TypeError for subclass receiver
+info: |
+ get RegExp.leftContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpLeftContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.leftContext;
+ },
+ "RegExp.leftContext getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp["$`"];
+ },
+ "RegExp.$` getter throws for subclass receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js
new file mode 100644
index 0000000000..748a09a522
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/prop-desc.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor for RegExp.rightContext
+info: |
+ RegExp.rightContext is an accessor property with attributes:
+ {
+ [[Enumerable]]: false,
+ [[Configurable]]: true,
+ [[Set]]: undefined,
+ }
+
+ get RegExp.rightContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]).
+includes: [propertyHelper.js]
+features: [legacy-regexp]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(RegExp, "rightContext");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "rightContext", {
+ enumerable: false,
+ configurable: true
+});
+
+desc = Object.getOwnPropertyDescriptor(RegExp, "$'");
+
+assert.sameValue(desc.set, undefined, "`set` property");
+assert.sameValue(typeof desc.get, "function", "`get` property");
+
+verifyProperty(RegExp, "$'", {
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js
new file mode 100644
index 0000000000..321f8d6707
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-cross-realm-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.rightContext throws a TypeError for cross-realm receiver
+info: |
+ get RegExp.rightContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,cross-realm,Reflect]
+---*/
+
+const other = $262.createRealm().global;
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "rightContext", other.RegExp);
+ },
+ "RegExp.rightContext getter throws for cross-realm receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ Reflect.get(RegExp, "$'", other.RegExp);
+ },
+ "RegExp.$' getter throws for cross-realm receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js
new file mode 100644
index 0000000000..01b5c065c9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-not-regexp-constructor.js
@@ -0,0 +1,62 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.rightContext throws a TypeError for non-%RegExp% receiver
+info: |
+ get RegExp.rightContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp]
+---*/
+
+["rightContext", "$'"].forEach(function (property) {
+ const desc = Object.getOwnPropertyDescriptor(RegExp, property);
+
+ // Similar to the other test verifying the descriptor, but split as properties can be removed or changed
+ assert.sameValue(typeof desc.get, "function", property + " getter");
+
+ // If SameValue(C, thisValue) is false, throw a TypeError exception.
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get();
+ },
+ "RegExp." + property + " getter throws for property descriptor receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(/ /);
+ },
+ "RegExp." + property + " getter throws for RegExp instance receiver"
+ );
+
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(RegExp.prototype);
+ },
+ "RegExp." + property + " getter throws for %RegExp.prototype% receiver"
+ );
+
+ [undefined, null, {}, true, false, 0, 1, "string"].forEach(function (value) {
+ assert.throws(
+ TypeError,
+ function () {
+ desc.get.call(value);
+ },
+ "RegExp." + property + ' getter throws for primitive "' + value + '" receiver'
+ );
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js
new file mode 100644
index 0000000000..4dbc82e23c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/rightContext/this-subclass-constructor.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: RegExp.rightContext throws a TypeError for subclass receiver
+info: |
+ get RegExp.rightContext
+
+ 1. Return ? GetLegacyRegExpStaticProperty(%RegExp%, this value, [[RegExpRightContext]]).
+
+ GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ).
+
+ 1. Assert C is an object that has an internal slot named internalSlotName.
+ 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
+ 3. ...
+features: [legacy-regexp,class]
+---*/
+
+class MyRegExp extends RegExp {}
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp.rightContext;
+ },
+ "RegExp.rightContext getter throws for subclass receiver"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ MyRegExp["$'"];
+ },
+ "RegExp.$' getter throws for subclass receiver"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/legacy-accessors/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed-lookbehind.js b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed-lookbehind.js
new file mode 100644
index 0000000000..9c8ab7ba6b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed-lookbehind.js
@@ -0,0 +1,17 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: prod-GroupSpecifier
+description: >
+ \k is parsed as IdentityEscape as look-behind assertion is not a GroupName.
+features: [regexp-named-groups, regexp-lookbehind]
+---*/
+
+assert(/\k<a>(?<=>)a/.test("k<a>a"));
+assert(/(?<=>)\k<a>/.test(">k<a>"));
+
+assert(/\k<a>(?<!a)a/.test("k<a>a"));
+assert(/(?<!a>)\k<a>/.test("k<a>"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed.js b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed.js
new file mode 100644
index 0000000000..b7dd55db09
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/non-unicode-malformed.js
@@ -0,0 +1,27 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Named groups in Unicode RegExps have some syntax errors and some
+ compatibility escape fallback behavior.
+esid: prod-GroupSpecifier
+features: [regexp-named-groups]
+includes: [compareArray.js]
+---*/
+
+assert(/\k<a>/.test("k<a>"));
+assert(/\k<4>/.test("k<4>"));
+assert(/\k<a/.test("k<a"));
+assert(/\k/.test("k"));
+
+assert(/(?<a>\a)/.test("a"));
+
+assert.compareArray(["k<a>"], "xxxk<a>xxx".match(/\k<a>/));
+assert.compareArray(["k<a"], "xxxk<a>xxx".match(/\k<a/));
+
+assert(/\k<a>(<a>x)/.test("k<a><a>x"));
+assert(/\k<a>\1/.test("k<a>\x01"));
+assert(/\1(b)\k<a>/.test("bk<a>"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/named-groups/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/Symbol.match-getter-recompiles-source.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/Symbol.match-getter-recompiles-source.js
new file mode 100644
index 0000000000..41e8cbaf19
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/Symbol.match-getter-recompiles-source.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-regexp.prototype-@@split
+description: >
+ Side-effects in IsRegExp may recompile the regular expression.
+info: |
+ 21.2.5.11 RegExp.prototype [ @@split ] ( string, limit )
+ ...
+ 4. Let C be ? SpeciesConstructor(rx, %RegExp%).
+ ...
+ 10. Let splitter be ? Construct(C, « rx, newFlags »).
+ ...
+
+ 21.2.3.1 RegExp ( pattern, flags )
+ 1. Let patternIsRegExp be ? IsRegExp(pattern).
+ ...
+
+features: [Symbol.match, Symbol.split]
+---*/
+
+var regExp = /a/;
+Object.defineProperty(regExp, Symbol.match, {
+ get: function() {
+ regExp.compile("b");
+ }
+});
+
+var result = regExp[Symbol.split]("abba");
+
+assert.sameValue(result.length, 3);
+assert.sameValue(result[0], "a");
+assert.sameValue(result[1], "");
+assert.sameValue(result[2], "a");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/toint32-limit-recompiles-source.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/toint32-limit-recompiles-source.js
new file mode 100644
index 0000000000..351407cf65
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/Symbol.split/toint32-limit-recompiles-source.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-regexp.prototype-@@split
+description: >
+ Side-effects in ToUint32 may recompile the regular expression.
+info: |
+ 21.2.5.11 RegExp.prototype [ @@split ] ( string, limit )
+ ...
+ 10. Let splitter be ? Construct(C, « rx, newFlags »).
+ ...
+ 13. If limit is undefined, let lim be 2^32-1; else let lim be ? ToUint32(limit).
+ ...
+
+features: [Symbol.split]
+---*/
+
+var regExp = /a/;
+var limit = {
+ valueOf: function() {
+ regExp.compile("b");
+ return -1;
+ }
+};
+
+var result = regExp[Symbol.split]("abba", limit);
+
+assert.sameValue(result.length, 3);
+assert.sameValue(result[0], "");
+assert.sameValue(result[1], "bb");
+assert.sameValue(result[2], "");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/B.RegExp.prototype.compile.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/B.RegExp.prototype.compile.js
new file mode 100644
index 0000000000..52b6cfa331
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/B.RegExp.prototype.compile.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.5.1
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (RegExp.prototype.compile)
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(RegExp.prototype, "compile", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/duplicate-named-capturing-groups-syntax.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/duplicate-named-capturing-groups-syntax.js
new file mode 100644
index 0000000000..a1ac2676a1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/duplicate-named-capturing-groups-syntax.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- regexp-duplicate-named-groups is not supported
+// Copyright 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-regexp.prototype.compile
+description: Runtime parsing of syntax for duplicate named capturing groups
+features: [regexp-duplicate-named-groups]
+---*/
+
+let r = /[ab]/;
+
+assert.throws(
+ SyntaxError,
+ () => r.compile("(?<x>a)(?<x>b)"),
+ "Duplicate named capturing groups in the same alternative do not parse"
+);
+
+let source = "(?<x>a)|(?<x>b)";
+r.compile(source);
+assert.sameValue(r.source, source, "Duplicate named capturing groups in separate alternatives parse correctly");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-string-invalid.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-string-invalid.js
new file mode 100644
index 0000000000..a7c8493656
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-string-invalid.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when flags is a string describing an invalid flag set
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ [...]
+ 3. If flags is undefined, let F be the empty String.
+ 4. Else, let F be ? ToString(flags).
+ 5. If F contains any code unit other than "g", "i", "m", "u", or "y" or if
+ it contains the same code unit more than once, throw a SyntaxError
+ exception.
+---*/
+
+var subject = /abcd/ig;
+
+assert.throws(SyntaxError, function() {
+ subject.compile('', 'igi');
+}, 'invalid flags: igi');
+
+assert.throws(SyntaxError, function() {
+ subject.compile('', 'gI');
+}, 'invalid flags: gI');
+
+assert.throws(SyntaxError, function() {
+ subject.compile('', 'w');
+}, 'invalid flags: w');
+
+assert.sameValue(
+ subject.toString(),
+ new RegExp('abcd', 'ig').toString(),
+ '[[OriginalSource]] internal slot'
+);
+
+assert.sameValue(
+ subject.test('AbCD'), true, '[[RegExpMatcher]] internal slot'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string-err.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string-err.js
new file mode 100644
index 0000000000..1fad177bd1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string-err.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when provided flags cannot be coerced to a string
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ [...]
+ 3. If flags is undefined, let F be the empty String.
+ 4. Else, let F be ? ToString(flags).
+features: [Symbol]
+---*/
+
+var symbol = Symbol('');
+var subject = /./;
+var badToString = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+subject.lastIndex = 99;
+
+assert.throws(Test262Error, function() {
+ /./.compile('', badToString);
+});
+
+assert.throws(TypeError, function() {
+ /./.compile('', symbol);
+});
+
+assert.sameValue(subject.lastIndex, 99);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string.js
new file mode 100644
index 0000000000..7044462a56
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-to-string.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when flags is a string describing a valid flag set
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ [...]
+ 3. If flags is undefined, let F be the empty String.
+ 4. Else, let F be ? ToString(flags).
+ [...]
+---*/
+
+var subject = /a/g;
+
+subject.compile('a', 'i');
+
+assert.sameValue(
+ subject.flags,
+ new RegExp('a', 'i').flags,
+ '[[OriginalFlags]] internal slot'
+);
+assert.sameValue(
+ subject.test('A'),
+ true,
+ '[[RegExpMatcher]] internal slot (addition of `i` flag)'
+);
+
+subject.lastIndex = 1;
+assert.sameValue(
+ subject.test('A'),
+ true,
+ '[[RegExpMatcher]] internal slot (removal of `g` flag)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-undefined.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-undefined.js
new file mode 100644
index 0000000000..29cb3b3fb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/flags-undefined.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when flags is undefined
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ [...]
+ 4. Else,
+ a. Let P be pattern.
+ b. Let F be flags.
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ [...]
+ 3. If flags is undefined, let F be the empty String.
+ [...]
+---*/
+
+var subject, result;
+
+subject = /abc/ig;
+
+result = subject.compile('def');
+
+assert.sameValue(result, subject, 'method return value (unspecified)');
+assert.sameValue(
+ subject.flags, new RegExp('def').flags, '[[OriginalFlags]] (unspecified)'
+);
+assert.sameValue(
+ subject.test('DEF'), false, '[[RegExpMatcher]] internal slot (unspecified)'
+);
+
+subject = /abc/gi;
+
+result = subject.compile('def', undefined);
+
+assert.sameValue(result, subject, 'method return value (explicit undefined)');
+assert.sameValue(
+ subject.flags,
+ new RegExp('def').flags,
+ '[[OriginalSource]] (explicit undefined)'
+);
+assert.sameValue(
+ subject.test('DEF'),
+ false,
+ '[[RegExpMatcher]] internal slot (explicit undefined)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/length.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/length.js
new file mode 100644
index 0000000000..ce648e692c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.5.1
+description: >
+ RegExp.prototype.compile.length is 2.
+info: |
+ RegExp.prototype.compile (pattern, flags )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(RegExp.prototype.compile, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 2
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/name.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/name.js
new file mode 100644
index 0000000000..2e35d280e3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.5.1
+description: >
+ RegExp.prototype.compile.name is "compile".
+info: |
+ RegExp.prototype.compile (pattern, flags )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(RegExp.prototype.compile, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "compile"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-distinct.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-distinct.js
new file mode 100644
index 0000000000..fed4f82364
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-distinct.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: RegExp is re-initialized when invoked with a distinct instance
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+---*/
+
+var subject = /abc/gim;
+var pattern = /def/;
+var result;
+subject.lastIndex = 23;
+pattern.lastIndex = 45;
+
+result = subject.compile(pattern);
+
+assert.sameValue(result, subject, 'method return value');
+assert.sameValue(subject.lastIndex, 0);
+assert.sameValue(pattern.lastIndex, 45);
+
+assert.sameValue(subject.toString(), new RegExp('def').toString());
+assert.sameValue(
+ subject.test('def'), true, '[[RegExpMatcher]] internal slot (source)'
+);
+assert.sameValue(
+ subject.test('DEF'), false, '[[RegExpMatch]] internal slot (flags)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-flags-defined.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-flags-defined.js
new file mode 100644
index 0000000000..6ea536960c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-flags-defined.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when provided pattern is a RegExp instance and flags are specified
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+---*/
+
+var re = /./;
+re.lastIndex = 23;
+
+assert.sameValue(typeof RegExp.prototype.compile, 'function');
+
+assert.throws(TypeError, function() {
+ re.compile(re, null);
+}, 'null');
+
+assert.throws(TypeError, function() {
+ re.compile(re, 0);
+}, 'numeric primitive');
+
+assert.throws(TypeError, function() {
+ re.compile(re, '');
+}, 'string primitive');
+
+assert.throws(TypeError, function() {
+ re.compile(re, false);
+}, 'boolean primitive');
+
+assert.throws(TypeError, function() {
+ re.compile(re, {});
+}, 'ordinary object');
+
+assert.throws(TypeError, function() {
+ re.compile(re, []);
+}, 'array exotic object');
+
+assert.sameValue(re.lastIndex, 23);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-immutable-lastindex.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-immutable-lastindex.js
new file mode 100644
index 0000000000..cb69aaa439
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-immutable-lastindex.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when `lastIndex` property of "this" value is non-writable
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ [...]
+ 12. Perform ? Set(obj, "lastIndex", 0, true).
+---*/
+
+var subject = /initial/;
+Object.defineProperty(subject, 'lastIndex', { value: 45, writable: false });
+
+assert.throws(TypeError, function() {
+ subject.compile(/updated/gi);
+});
+
+assert.sameValue(
+ subject.toString(),
+ new RegExp('updated', 'gi').toString(),
+ '[[OriginalSource]] internal slot'
+);
+assert.sameValue(subject.lastIndex, 45);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-props.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-props.js
new file mode 100644
index 0000000000..f723c00174
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-props.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Properties are not referenced when provided pattern is a RegExp instance
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+---*/
+
+var thisValue = /abc/gim;
+var pattern = /def/mig;
+var flagsCount = 0;
+var globalCount = 0;
+var ignoreCaseCount = 0;
+var multilineCount = 0;
+var stickyCount = 0;
+var unicodeCount = 0;
+var counters = {
+ flags: {
+ get: function() {
+ flagsCount += 1;
+ }
+ },
+ global: {
+ get: function() {
+ globalCount += 1;
+ }
+ },
+ ignoreCase: {
+ get: function() {
+ ignoreCaseCount += 1;
+ }
+ },
+ multiline: {
+ get: function() {
+ multilineCount += 1;
+ }
+ },
+ sticky: {
+ get: function() {
+ stickyCount += 1;
+ }
+ },
+ unicode: {
+ get: function() {
+ unicodeCount += 1;
+ }
+ }
+};
+
+Object.defineProperties(thisValue, counters);
+Object.defineProperties(pattern, counters);
+
+thisValue.compile(thisValue);
+thisValue.compile(pattern);
+thisValue.compile(thisValue);
+
+assert.sameValue(flagsCount, 0, '`flags` property not accessed');
+assert.sameValue(globalCount, 0, '`global` property not accessed');
+assert.sameValue(ignoreCaseCount, 0, '`ignoreCase` property not accessed');
+assert.sameValue(multilineCount, 0, '`multiline` property not accessed');
+assert.sameValue(stickyCount, 0, '`sticky` property not accessed');
+assert.sameValue(unicodeCount, 0, '`unicode` property not accessed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-same.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-same.js
new file mode 100644
index 0000000000..b239e0e48b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-regexp-same.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-regexp.prototype.compile
+es6id: B.2.5.1
+description: RegExp is re-initialized when invoked with the same instance
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+---*/
+
+var subject = /abc/gim;
+var result;
+subject.lastIndex = 23;
+
+result = subject.compile(subject);
+
+assert.sameValue(result, subject, 'method return value');
+assert.sameValue(
+ subject.toString(),
+ new RegExp('abc', 'gim').toString(),
+ '[[OriginalSource]] internal slot'
+);
+assert.sameValue(subject.lastIndex, 0);
+assert.sameValue(subject.test('aBc'), true, '[[RegExpMatcher]] internal slot');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js
new file mode 100644
index 0000000000..d0c3cd6d5f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when pattern is a string describing an invalid pattern (unicode)
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 6. If F contains "u", let BMP be false; else let BMP be true.
+ 7. If BMP is true, then
+ a. Parse P using the grammars in 21.2.1 and interpreting each of its
+ 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not
+ applied to the elements. The goal symbol for the parse is Pattern.
+ Throw a SyntaxError exception if P did not conform to the grammar, if
+ any elements of P were not matched by the parse, or if any Early
+ Error conditions exist.
+ [...]
+---*/
+
+var subject = /test262/ig;
+
+assert.throws(SyntaxError, function() {
+ subject.compile('{', 'u');
+}, 'invalid pattern: {');
+
+assert.throws(SyntaxError, function() {
+ subject.compile('\\2', 'u');
+}, 'invalid pattern: \\2');
+
+assert.sameValue(
+ subject.toString(),
+ new RegExp('test262', 'ig').toString(),
+ '[[OriginalSource]] internal slot'
+);
+assert.sameValue(
+ subject.test('tEsT262'), true, '[[RegExpMatcher]] internal slot'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid.js
new file mode 100644
index 0000000000..471e8da688
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when pattern is a string describing an invalid pattern
+ (non-unicode)
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 6. If F contains "u", let BMP be false; else let BMP be true.
+ 7. If BMP is true, then
+ [...]
+ 8. Else,
+ a. Parse P using the grammars in 21.2.1 and interpreting P as UTF-16
+ encoded Unicode code points (6.1.4). The goal symbol for the parse is
+ Pattern[U]. Throw a SyntaxError exception if P did not conform to the
+ grammar, if any elements of P were not matched by the parse, or if
+ any Early Error conditions exist.
+---*/
+
+var subject = /test262/ig;
+
+assert.throws(SyntaxError, function() {
+ subject.compile('?');
+}, 'invalid pattern: ?');
+
+assert.throws(SyntaxError, function() {
+ subject.compile('.{2,1}');
+}, 'invalid pattern: .{2,1}');
+
+assert.sameValue(
+ subject.toString(),
+ new RegExp('test262', 'ig').toString(),
+ '[[OriginalSource]] internal slot'
+);
+
+assert.sameValue(
+ subject.test('TEsT262'), true, '[[RegExpMatcher]] internal slot'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-u.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-u.js
new file mode 100644
index 0000000000..e3840230fb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string-u.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when pattern is a string describing a valid pattern (unicode)
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 6. If F contains "u", let BMP be false; else let BMP be true.
+ 7. If BMP is true, then
+ a. Parse P using the grammars in 21.2.1 and interpreting each of its
+ 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not
+ applied to the elements. The goal symbol for the parse is Pattern.
+ Throw a SyntaxError exception if P did not conform to the grammar, if
+ any elements of P were not matched by the parse, or if any Early
+ Error conditions exist.
+ b. Let patternCharacters be a List whose elements are the code unit
+ elements of P.
+ [...]
+---*/
+
+var subject = /original value/ig;
+
+subject.compile('[\ud834\udf06]', 'u');
+
+assert.sameValue(
+ subject.source,
+ new RegExp('[\ud834\udf06]', 'u').source,
+ '[[OriginalSource]] internal slot'
+);
+assert.sameValue(
+ subject.test('original value'),
+ false,
+ '[[RegExpMatcher]] internal slot (source)'
+);
+assert.sameValue(
+ subject.test('\ud834'), false, '[[RegExpMatcher]] internal slot (flags #1)'
+);
+assert.sameValue(
+ subject.test('\udf06'), false, '[[RegExpMatcher]] internal slot (flags #2)'
+);
+assert.sameValue(
+ subject.test('\ud834\udf06'),
+ true,
+ '[[RegExpMatcher]] internal slot (flags #3)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string.js
new file mode 100644
index 0000000000..57c9a82e41
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-string.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when pattern is a string describing a valid pattern (non-unicode)
+info: |
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 6. If F contains "u", let BMP be false; else let BMP be true.
+ 7. If BMP is true, then
+ [...]
+ 8. Else,
+ a. Parse P using the grammars in 21.2.1 and interpreting P as UTF-16
+ encoded Unicode code points (6.1.4). The goal symbol for the parse is
+ Pattern[U]. Throw a SyntaxError exception if P did not conform to the
+ grammar, if any elements of P were not matched by the parse, or if
+ any Early Error conditions exist.
+ b. Let patternCharacters be a List whose elements are the code points
+ resulting from applying UTF-16 decoding to P's sequence of elements.
+ [...]
+---*/
+
+var subject = /original value/ig;
+
+subject.compile('new value');
+
+assert.sameValue(
+ subject.source,
+ new RegExp('new value').source,
+ '[[OriginalSource]] internal slot'
+);
+assert.sameValue(
+ subject.test('original value'), false, '[[RegExpMatcher]] internal slot'
+);
+assert.sameValue(
+ subject.test('new value'), true, '[[RegExpMatcher]] internal slot'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-to-string-err.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-to-string-err.js
new file mode 100644
index 0000000000..64df03654a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-to-string-err.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when provided pattern cannot be coerced to a string
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ a. If flags is not undefined, throw a TypeError exception.
+ b. Let P be the value of pattern's [[OriginalSource]] internal slot.
+ c. Let F be the value of pattern's [[OriginalFlags]] internal slot.
+ 4. Else,
+ [...]
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 1. If pattern is undefined, let P be the empty String.
+ 2. Else, let P be ? ToString(pattern).
+features: [Symbol]
+---*/
+
+var symbol = Symbol('');
+var subject = /./;
+var badToString = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+subject.lastIndex = 99;
+
+assert.throws(Test262Error, function() {
+ /./.compile(badToString);
+});
+
+assert.throws(TypeError, function() {
+ /./.compile(symbol);
+});
+
+assert.sameValue(subject.lastIndex, 99);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-undefined.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-undefined.js
new file mode 100644
index 0000000000..52328d262d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/pattern-undefined.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when pattern is undefined
+info: |
+ [...]
+ 3. If Type(pattern) is Object and pattern has a [[RegExpMatcher]] internal
+ slot, then
+ [...]
+ 4. Else,
+ a. Let P be pattern.
+ b. Let F be flags.
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.3.2.2 Runtime Semantics: RegExpInitialize
+
+ 1. If pattern is undefined, let P be the empty String.
+ [...]
+---*/
+
+var subject;
+
+subject = /abc/;
+assert.sameValue(
+ subject.compile(), subject, 'method return value (unspecified)'
+);
+assert.sameValue(
+ subject.source, new RegExp('').source, '[[OriginalSource]] (unspecified)'
+);
+assert.sameValue(
+ subject.test(''), true, '[[RegExpMatcher]] internal slot (unspecified)'
+);
+
+subject = /abc/;
+assert.sameValue(
+ subject.compile(undefined),
+ subject,
+ 'method return value (explicit undefined)'
+);
+assert.sameValue(
+ subject.source,
+ new RegExp('').source,
+ '[[OriginalSource]] (explicit undefined)'
+);
+assert.sameValue(
+ subject.test(''),
+ true,
+ '[[RegExpMatcher]] internal slot (explicit undefined)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js
new file mode 100644
index 0000000000..5c4f9a8234
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+description: RegExp.prototype.compile throws a TypeError for cross-realm calls
+features: [legacy-regexp,cross-realm]
+---*/
+
+const other = $262.createRealm().global;
+
+const regexp = new RegExp("");
+const otherRealm_regexp = new other.RegExp("");
+
+assert.throws(
+ TypeError,
+ function () {
+ RegExp.prototype.compile.call(otherRealm_regexp);
+ },
+ "`RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError"
+);
+
+assert.throws(
+ other.TypeError,
+ function () {
+ other.RegExp.prototype.compile.call(regexp);
+ },
+ "`other.RegExp.prototype.compile.call(regexp)` throws TypeError"
+);
+
+assert.sameValue(
+ otherRealm_regexp.compile(),
+ otherRealm_regexp,
+ "`otherRealm_regexp.compile()` is SameValue with `otherRealm_regexp`"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-not-object.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-not-object.js
new file mode 100644
index 0000000000..77424a0062
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-not-object.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: Behavior when "this" value is not an Object
+info: |
+ 1. Let O be the this value.
+ 2. If Type(O) is not Object or Type(O) is Object and O does not have a
+ [[RegExpMatcher]] internal slot, then
+ a. Throw a TypeError exception.
+features: [Symbol]
+---*/
+
+var compile = RegExp.prototype.compile;
+var symbol = Symbol('');
+
+assert.sameValue(typeof compile, 'function');
+
+assert.throws(TypeError, function() {
+ compile.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ compile.call(null);
+}, 'null');
+
+assert.throws(TypeError, function() {
+ compile.call(23);
+}, 'number');
+
+assert.throws(TypeError, function() {
+ compile.call(true);
+}, 'boolean');
+
+assert.throws(TypeError, function() {
+ compile.call('/string/');
+}, 'string');
+
+assert.throws(TypeError, function() {
+ compile.call(symbol);
+}, 'symbol');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-obj-not-regexp.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-obj-not-regexp.js
new file mode 100644
index 0000000000..785fccacff
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-obj-not-regexp.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+es6id: B.2.5.1
+description: >
+ Behavior when "this" value is an Object without a [[RegExpMatcher]]
+ internal slot
+info: |
+ 1. Let O be the this value.
+ 2. If Type(O) is not Object or Type(O) is Object and O does not have a
+ [[RegExpMatcher]] internal slot, then
+ a. Throw a TypeError exception.
+---*/
+
+var compile = RegExp.prototype.compile;
+
+assert.sameValue(typeof compile, 'function');
+
+assert.throws(TypeError, function() {
+ compile.call({});
+}, 'ordinary object');
+
+assert.throws(TypeError, function() {
+ compile.call([]);
+}, 'array exotic object');
+
+assert.throws(TypeError, function() {
+ compile.call(arguments);
+}, 'arguments exotic object');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js
new file mode 100644
index 0000000000..66f6e3f5a6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- legacy-regexp is not supported
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regexp.prototype.compile
+description: RegExp.prototype.compile throws a TypeError for calls on subclasses
+features: [legacy-regexp,class]
+---*/
+
+const subclass_regexp = new (class extends RegExp {})("");
+
+assert.throws(
+ TypeError,
+ function () {
+ subclass_regexp.compile();
+ },
+ "`subclass_regexp.compile()` throws TypeError"
+);
+
+assert.throws(
+ TypeError,
+ function () {
+ RegExp.prototype.compile.call(subclass_regexp);
+ },
+ "`RegExp.prototype.compile.call(subclass_regexp)` throws TypeError"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/browser.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/order-after-compile.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/order-after-compile.js
new file mode 100644
index 0000000000..c445800923
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/order-after-compile.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-get-regexp.prototype.flags
+description: >
+ The flags come in the same order in a new instance produced by RegExp.prototype.compile
+info: |
+ B.2.5.1 RegExp.prototype.compile ( pattern, flags )
+
+ ...
+ 5. Return ? RegExpInitialize(O, P, F).
+
+ 21.2.5.3 get RegExp.prototype.flags
+
+ ...
+ 4. Let global be ToBoolean(? Get(R, "global")).
+ 5. If global is true, append "g" as the last code unit of result.
+ 6. Let ignoreCase be ToBoolean(? Get(R, "ignoreCase")).
+ 7. If ignoreCase is true, append "i" as the last code unit of result.
+ 8. Let multiline be ToBoolean(? Get(R, "multiline")).
+ 9. If multiline is true, append "m" as the last code unit of result.
+ 10. Let dotAll be ToBoolean(? Get(R, "dotAll")).
+ 11. If dotAll is true, append "s" as the last code unit of result.
+ 12. Let unicode be ToBoolean(? Get(R, "unicode")).
+ 13. If unicode is true, append "u" as the last code unit of result.
+ 14. Let sticky be ToBoolean(? Get(R, "sticky")).
+ 15. If sticky is true, append "y" as the last code unit of result.
+ 14. Return result.
+features: [regexp-dotall]
+---*/
+
+let re = /(?:)/;
+re.compile("(?:)", "imsuyg");
+assert.sameValue(re.flags, "gimsuy");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/flags/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/prototype/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/prototype/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/RegExp/shell.js b/js/src/tests/test262/annexB/built-ins/RegExp/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/RegExp/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/browser.js b/js/src/tests/test262/annexB/built-ins/String/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/B.2.3.2.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/B.2.3.2.js
new file mode 100644
index 0000000000..6b8511876e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/B.2.3.2.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.anchor returns a string of HTML describing a single HTML
+ anchor element. The element's content is the `this` value of the function
+ invocation, coerced to a string. If specified, the first argument will be
+ coerced to a string, escaped, and set as the element's `name` attribute.
+ es6id: B.2.3.2
+---*/
+
+assert.sameValue('_'.anchor('b'), '<a name="b">_</a>');
+assert.sameValue('<'.anchor('<'), '<a name="<"><</a>');
+assert.sameValue('_'.anchor(0x2A), '<a name="42">_</a>');
+assert.sameValue('_'.anchor('\x22'), '<a name="&quot;">_</a>');
+assert.sameValue(String.prototype.anchor.call(0x2A, 0x2A), '<a name="42">42</a>');
+assert.throws(TypeError, function() {
+ String.prototype.anchor.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.anchor.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/attr-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/attr-tostring-err.js
new file mode 100644
index 0000000000..bf6a3eae21
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/attr-tostring-err.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.anchor
+es6id: B.2.3.2
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ [...]
+ 4. If attribute is not the empty String, then
+ a. Let V be ? ToString(value).
+---*/
+
+var attr = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.anchor(attr);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/length.js
new file mode 100644
index 0000000000..9df190d4a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.2
+description: >
+ String.prototype.anchor.length is 1.
+info: |
+ String.prototype.anchor ( name )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.anchor, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/name.js
new file mode 100644
index 0000000000..4d961bd1a9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.2
+description: >
+ String.prototype.anchor.name is "anchor".
+info: |
+ String.prototype.anchor ( name )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.anchor, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "anchor"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/not-a-constructor.js
new file mode 100644
index 0000000000..ca59226cbf
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.anchor does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.anchor),
+ false,
+ 'isConstructor(String.prototype.anchor) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.anchor();
+}, '`new String.prototype.anchor()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/prop-desc.js
new file mode 100644
index 0000000000..b1412c4a1c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.anchor
+es6id: B.2.3.2
+description: Property descriptor for String.prototype.anchor
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "anchor", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/this-val-tostring-err.js
new file mode 100644
index 0000000000..c6d9d25d41
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/anchor/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.anchor
+es6id: B.2.3.2
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.anchor.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/B.2.3.3.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/B.2.3.3.js
new file mode 100644
index 0000000000..16a179283f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/B.2.3.3.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.big returns a string of HTML describing a single HTML
+ big element. The element's content is the `this` value of the function
+ invocation, coerced to a string.
+ es6id: B.2.3.3
+---*/
+
+assert.sameValue('_'.big(), '<big>_</big>');
+assert.sameValue('<'.big(), '<big><</big>');
+assert.sameValue(String.prototype.big.call(0x2A), '<big>42</big>');
+assert.throws(TypeError, function() {
+ String.prototype.big.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.big.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/length.js
new file mode 100644
index 0000000000..bc94e5fdc4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.3
+description: >
+ String.prototype.big.length is 0.
+info: |
+ String.prototype.big ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.big, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/name.js
new file mode 100644
index 0000000000..29dad81234
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.3
+description: >
+ String.prototype.big.name is "big".
+info: |
+ String.prototype.big ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.big, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "big"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/not-a-constructor.js
new file mode 100644
index 0000000000..f2e5f3bfc7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/not-a-constructor.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.big does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(String.prototype.big), false, 'isConstructor(String.prototype.big) must return false');
+
+assert.throws(TypeError, () => {
+ new String.prototype.big();
+}, '`new String.prototype.big()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/prop-desc.js
new file mode 100644
index 0000000000..80a2b7ef72
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.big
+es6id: B.2.3.3
+description: Property descriptor for String.prototype.big
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "big", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/big/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/big/this-val-tostring-err.js
new file mode 100644
index 0000000000..63326e834a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/big/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.big
+es6id: B.2.3.3
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.big.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/B.2.3.4.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/B.2.3.4.js
new file mode 100644
index 0000000000..5aa5620c82
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/B.2.3.4.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.blink returns a string of HTML describing a single HTML
+ blink element. The element's content is the `this` value of the function
+ invocation, coerced to a string.
+ es6id: B.2.3.4
+---*/
+
+assert.sameValue('_'.blink(), '<blink>_</blink>');
+assert.sameValue('<'.blink(), '<blink><</blink>');
+assert.sameValue(String.prototype.blink.call(0x2A), '<blink>42</blink>');
+assert.throws(TypeError, function() {
+ String.prototype.blink.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.blink.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/length.js
new file mode 100644
index 0000000000..06c85b49dc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.4
+description: >
+ String.prototype.blink.length is 0.
+info: |
+ String.prototype.blink ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.blink, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/name.js
new file mode 100644
index 0000000000..617b2d6993
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.4
+description: >
+ String.prototype.blink.name is "blink".
+info: |
+ String.prototype.blink ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.blink, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "blink"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/not-a-constructor.js
new file mode 100644
index 0000000000..73d5488203
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.blink does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.blink),
+ false,
+ 'isConstructor(String.prototype.blink) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.blink();
+}, '`new String.prototype.blink()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/prop-desc.js
new file mode 100644
index 0000000000..8c875db468
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.blink
+es6id: B.2.3.4
+description: Property descriptor for String.prototype.blink
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "blink", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/blink/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/this-val-tostring-err.js
new file mode 100644
index 0000000000..4a2f900e23
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/blink/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.blink
+es6id: B.2.3.4
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.blink.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/B.2.3.5.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/B.2.3.5.js
new file mode 100644
index 0000000000..3a9a73052e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/B.2.3.5.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.bold returns a string of HTML describing a single HTML
+ bold element. The element's content is the `this` value of the function
+ invocation, coerced to a string.
+ es6id: B.2.3.5
+---*/
+
+assert.sameValue('_'.bold(), '<b>_</b>');
+assert.sameValue('<'.bold(), '<b><</b>');
+assert.sameValue(String.prototype.bold.call(0x2A), '<b>42</b>');
+assert.throws(TypeError, function() {
+ String.prototype.bold.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.bold.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/length.js
new file mode 100644
index 0000000000..151964b7ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.5
+description: >
+ String.prototype.bold.length is 0.
+info: |
+ String.prototype.bold ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.bold, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/name.js
new file mode 100644
index 0000000000..21c7beafd0
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.5
+description: >
+ String.prototype.bold.name is "bold".
+info: |
+ String.prototype.bold ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.bold, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "bold"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/not-a-constructor.js
new file mode 100644
index 0000000000..1f8a7a155d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.bold does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.bold),
+ false,
+ 'isConstructor(String.prototype.bold) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.bold();
+}, '`new String.prototype.bold()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/prop-desc.js
new file mode 100644
index 0000000000..1eb27ef8bc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.bold
+es6id: B.2.3.5
+description: Property descriptor for String.prototype.bold
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "bold", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/bold/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/this-val-tostring-err.js
new file mode 100644
index 0000000000..7f1fdd05ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/bold/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.bold
+es6id: B.2.3.5
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.bold.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/B.2.3.6.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/B.2.3.6.js
new file mode 100644
index 0000000000..2c20e91f4c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/B.2.3.6.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.fixed returns a string of HTML describing a single HTML
+ teletype text element. The element's content is the `this` value of the
+ function invocation, coerced to a string.
+ es6id: B.2.3.6
+---*/
+
+assert.sameValue('_'.fixed(), '<tt>_</tt>');
+assert.sameValue('<'.fixed(), '<tt><</tt>');
+assert.sameValue(String.prototype.fixed.call(0x2A), '<tt>42</tt>');
+assert.throws(TypeError, function() {
+ String.prototype.fixed.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.fixed.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/length.js
new file mode 100644
index 0000000000..bc2d83974b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.6
+description: >
+ String.prototype.fixed.length is 0.
+info: |
+ String.prototype.fixed ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fixed, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/name.js
new file mode 100644
index 0000000000..a5b546cd76
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.6
+description: >
+ String.prototype.fixed.name is "fixed".
+info: |
+ String.prototype.fixed ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fixed, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "fixed"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/not-a-constructor.js
new file mode 100644
index 0000000000..64fa0c534d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.fixed does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.fixed),
+ false,
+ 'isConstructor(String.prototype.fixed) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.fixed();
+}, '`new String.prototype.fixed()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/prop-desc.js
new file mode 100644
index 0000000000..c6691e668b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fixed
+es6id: B.2.3.6
+description: Property descriptor for String.prototype.fixed
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "fixed", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/this-val-tostring-err.js
new file mode 100644
index 0000000000..96b339a0f0
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fixed/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fixed
+es6id: B.2.3.6
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.fixed.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/B.2.3.7.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/B.2.3.7.js
new file mode 100644
index 0000000000..497e24654d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/B.2.3.7.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.fontcolor returns a string of HTML describing a single
+ HTML font element. The element's content is the `this` value of the
+ function invocation, coerced to a string. If specified, the first argument
+ will be coerced to a string, escaped, and set as the element's `color`
+ attribute.
+ es6id: B.2.3.7
+---*/
+
+assert.sameValue('_'.fontcolor('b'), '<font color="b">_</font>');
+assert.sameValue('<'.fontcolor('<'), '<font color="<"><</font>');
+assert.sameValue('_'.fontcolor(0x2A), '<font color="42">_</font>');
+assert.sameValue('_'.fontcolor('\x22'), '<font color="&quot;">_</font>');
+assert.sameValue(String.prototype.fontcolor.call(0x2A, 0x2A),
+ '<font color="42">42</font>');
+assert.throws(TypeError, function() {
+ String.prototype.fontcolor.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.fontcolor.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/attr-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/attr-tostring-err.js
new file mode 100644
index 0000000000..bc4604f7b9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/attr-tostring-err.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontcolor
+es6id: B.2.3.7
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ [...]
+ 4. If attribute is not the empty String, then
+ a. Let V be ? ToString(value).
+---*/
+
+var attr = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.fontcolor(attr);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/length.js
new file mode 100644
index 0000000000..d12fa78837
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.7
+description: >
+ String.prototype.fontcolor.length is 1.
+info: |
+ String.prototype.fontcolor ( color )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fontcolor, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/name.js
new file mode 100644
index 0000000000..237ce1debc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.7
+description: >
+ String.prototype.fontcolor.name is "fontcolor".
+info: |
+ String.prototype.fontcolor ( color )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fontcolor, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "fontcolor"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/not-a-constructor.js
new file mode 100644
index 0000000000..a5bfa4415c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.fontcolor does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.fontcolor),
+ false,
+ 'isConstructor(String.prototype.fontcolor) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.fontcolor();
+}, '`new String.prototype.fontcolor()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/prop-desc.js
new file mode 100644
index 0000000000..0473c209ce
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontcolor
+es6id: B.2.3.7
+description: Property descriptor for String.prototype.fontcolor
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "fontcolor", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/this-val-tostring-err.js
new file mode 100644
index 0000000000..2fdacd804b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontcolor/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontcolor
+es6id: B.2.3.7
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.fontcolor.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/B.2.3.8.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/B.2.3.8.js
new file mode 100644
index 0000000000..b6f51d9f3b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/B.2.3.8.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.fontsize returns a string of HTML describing a single
+ HTML font element. The element's content is the `this` value of the
+ function invocation, coerced to a string. If specified, the first argument
+ will be coerced to a string, escaped, and set as the element's `size`
+ attribute.
+ es6id: B.2.3.8
+---*/
+
+assert.sameValue('_'.fontsize('b'), '<font size="b">_</font>');
+assert.sameValue('<'.fontsize('<'), '<font size="<"><</font>');
+assert.sameValue('_'.fontsize(0x2A), '<font size="42">_</font>');
+assert.sameValue('_'.fontsize('\x22'), '<font size="&quot;">_</font>');
+assert.sameValue(String.prototype.fontsize.call(0x2A, 0x2A),
+ '<font size="42">42</font>');
+assert.throws(TypeError, function() {
+ String.prototype.fontsize.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.fontsize.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/attr-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/attr-tostring-err.js
new file mode 100644
index 0000000000..be60430f40
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/attr-tostring-err.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontsize
+es6id: B.2.3.8
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ [...]
+ 4. If attribute is not the empty String, then
+ a. Let V be ? ToString(value).
+---*/
+
+var attr = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.fontsize(attr);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/length.js
new file mode 100644
index 0000000000..94cf9e7f4e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.8
+description: >
+ String.prototype.fontsize.length is 1.
+info: |
+ String.prototype.fontsize ( size )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fontsize, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/name.js
new file mode 100644
index 0000000000..42d7b00105
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.8
+description: >
+ String.prototype.fontsize.name is "fontsize".
+info: |
+ String.prototype.fontsize ( color )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.fontsize, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "fontsize"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/not-a-constructor.js
new file mode 100644
index 0000000000..d221a1348a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.fontsize does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.fontsize),
+ false,
+ 'isConstructor(String.prototype.fontsize) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.fontsize();
+}, '`new String.prototype.fontsize()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/prop-desc.js
new file mode 100644
index 0000000000..d25aceb2e8
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontsize
+es6id: B.2.3.8
+description: Property descriptor for String.prototype.fontsize
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "fontsize", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/this-val-tostring-err.js
new file mode 100644
index 0000000000..9bb7b11da6
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/fontsize/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.fontsize
+es6id: B.2.3.8
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.fontsize.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/B.2.3.9.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/B.2.3.9.js
new file mode 100644
index 0000000000..5421037edb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/B.2.3.9.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.italics returns a string of HTML describing a single HTML
+ italic element. The element's content is the `this` value of the function
+ invocation, coerced to a string.
+ es6id: B.2.3.9
+---*/
+
+assert.sameValue('_'.italics(), '<i>_</i>');
+assert.sameValue('<'.italics(), '<i><</i>');
+assert.sameValue(String.prototype.italics.call(0x2A), '<i>42</i>');
+assert.throws(TypeError, function() {
+ String.prototype.italics.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.italics.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/length.js
new file mode 100644
index 0000000000..1c2a517ffa
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.9
+description: >
+ String.prototype.italics.length is 0.
+info: |
+ String.prototype.italics ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.italics, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/name.js
new file mode 100644
index 0000000000..56139bf62b
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.9
+description: >
+ String.prototype.italics.name is "italics".
+info: |
+ String.prototype.italics ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.italics, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "italics"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/not-a-constructor.js
new file mode 100644
index 0000000000..4833d9b0e5
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.italics does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.italics),
+ false,
+ 'isConstructor(String.prototype.italics) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.italics();
+}, '`new String.prototype.italics()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/prop-desc.js
new file mode 100644
index 0000000000..041b5ad7f4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.italics
+es6id: B.2.3.9
+description: Property descriptor for String.prototype.italics
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "italics", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/italics/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/this-val-tostring-err.js
new file mode 100644
index 0000000000..db693918dd
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/italics/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.italics
+es6id: B.2.3.9
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.italics.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/B.2.3.10.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/B.2.3.10.js
new file mode 100644
index 0000000000..01d0268cdd
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/B.2.3.10.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.link returns a string of HTML describing a single HTML
+ link element. The element's content is the `this` value of the function
+ invocation, coerced to a string. If specified, the first argument will be
+ coerced to a string, escaped, and set as the element's `href` attribute.
+ es6id: B.2.3.10
+---*/
+
+assert.sameValue('_'.link('b'), '<a href="b">_</a>');
+assert.sameValue('<'.link('<'), '<a href="<"><</a>');
+assert.sameValue('_'.link(0x2A), '<a href="42">_</a>');
+assert.sameValue('_'.link('\x22'), '<a href="&quot;">_</a>');
+assert.sameValue(String.prototype.link.call(0x2A, 0x2A), '<a href="42">42</a>');
+assert.throws(TypeError, function() {
+ String.prototype.link.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.link.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/attr-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/attr-tostring-err.js
new file mode 100644
index 0000000000..88b6d3e301
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/attr-tostring-err.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.link
+es6id: B.2.3.10
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ [...]
+ 4. If attribute is not the empty String, then
+ a. Let V be ? ToString(value).
+---*/
+
+var attr = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.link(attr);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/length.js
new file mode 100644
index 0000000000..f51904e982
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.10
+description: >
+ String.prototype.link.length is 1.
+info: |
+ String.prototype.link ( url )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.link, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/name.js
new file mode 100644
index 0000000000..fb7ea3ee2a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.10
+description: >
+ String.prototype.link.name is "link".
+info: |
+ String.prototype.link ( url )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.link, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "link"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/not-a-constructor.js
new file mode 100644
index 0000000000..afd8d81733
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.link does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.link),
+ false,
+ 'isConstructor(String.prototype.link) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.link();
+}, '`new String.prototype.link()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/prop-desc.js
new file mode 100644
index 0000000000..75bf7df731
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.link
+es6id: B.2.3.10
+description: Property descriptor for String.prototype.link
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "link", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/link/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/link/this-val-tostring-err.js
new file mode 100644
index 0000000000..b14c932f59
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/link/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.link
+es6id: B.2.3.10
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.link.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/match/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/match/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/match/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/match/custom-matcher-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/match/custom-matcher-emulates-undefined.js
new file mode 100644
index 0000000000..55e6d28feb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/match/custom-matcher-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.match
+description: >
+ [[IsHTMLDDA]] object as @@match method gets called.
+info: |
+ String.prototype.match ( regexp )
+
+ [...]
+ 2. If regexp is neither undefined nor null, then
+ a. Let matcher be ? GetMethod(regexp, @@match).
+ b. If matcher is not undefined, then
+ i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.match, IsHTMLDDA]
+---*/
+
+var regexp = $262.IsHTMLDDA;
+var matcherGets = 0;
+Object.defineProperty(regexp, Symbol.match, {
+ get: function() {
+ matcherGets += 1;
+ return regexp;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".match(regexp), null);
+assert.sameValue(matcherGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/match/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/match/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/match/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/custom-matcher-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/custom-matcher-emulates-undefined.js
new file mode 100644
index 0000000000..5abb9d10d3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/custom-matcher-emulates-undefined.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.matchall
+description: >
+ [[IsHTMLDDA]] object as @@matchAll method gets called.
+info: |
+ String.prototype.matchAll ( regexp )
+
+ [...]
+ 2. If regexp is neither undefined nor null, then
+ [...]
+ c. Let matcher be ? GetMethod(regexp, @@matchAll).
+ d. If matcher is not undefined, then
+ i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.matchAll, String.prototype.matchAll, IsHTMLDDA]
+---*/
+
+var regexp = $262.IsHTMLDDA;
+var matcherGets = 0;
+Object.defineProperty(regexp, Symbol.matchAll, {
+ get: function() {
+ matcherGets += 1;
+ return regexp;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".matchAll(regexp), null);
+assert.sameValue(matcherGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/matchAll/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replace/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replace/custom-replacer-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/custom-replacer-emulates-undefined.js
new file mode 100644
index 0000000000..07c5ad606f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/custom-replacer-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.replace
+description: >
+ [[IsHTMLDDA]] object as @@replace method gets called.
+info: |
+ String.prototype.replace ( searchValue, replaceValue )
+
+ [...]
+ 2. If searchValue is neither undefined nor null, then
+ a. Let replacer be ? GetMethod(searchValue, @@replace).
+ b. If replacer is not undefined, then
+ i. Return ? Call(replacer, searchValue, « O, replaceValue »).
+features: [Symbol.replace, IsHTMLDDA]
+---*/
+
+var searchValue = $262.IsHTMLDDA;
+var replacerGets = 0;
+Object.defineProperty(searchValue, Symbol.replace, {
+ get: function() {
+ replacerGets += 1;
+ return searchValue;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".replace(searchValue), null);
+assert.sameValue(replacerGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replace/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replace/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/custom-replacer-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/custom-replacer-emulates-undefined.js
new file mode 100644
index 0000000000..7fec73440a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/custom-replacer-emulates-undefined.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.replaceall
+description: >
+ [[IsHTMLDDA]] object as @@replace method gets called.
+info: |
+ String.prototype.replaceAll ( searchValue, replaceValue )
+
+ [...]
+ 2. If searchValue is neither undefined nor null, then
+ [...]
+ c. Let replacer be ? GetMethod(searchValue, @@replace).
+ d. If replacer is not undefined, then
+ i. Return ? Call(replacer, searchValue, « O, replaceValue »).
+features: [Symbol.replace, String.prototype.replaceAll, IsHTMLDDA]
+---*/
+
+var searchValue = $262.IsHTMLDDA;
+var replacerGets = 0;
+Object.defineProperty(searchValue, Symbol.replace, {
+ get: function() {
+ replacerGets += 1;
+ return searchValue;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".replaceAll(searchValue), null);
+assert.sameValue(replacerGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/replaceAll/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/search/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/search/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/search/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/search/custom-searcher-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/search/custom-searcher-emulates-undefined.js
new file mode 100644
index 0000000000..d96bbb1ff7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/search/custom-searcher-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.search
+description: >
+ [[IsHTMLDDA]] object as @@search method gets called.
+info: |
+ String.prototype.search ( regexp )
+
+ [...]
+ 2. If regexp is neither undefined nor null, then
+ a. Let searcher be ? GetMethod(regexp, @@search).
+ b. If searcher is not undefined, then
+ i. Return ? Call(searcher, regexp, « O »).
+features: [Symbol.search, IsHTMLDDA]
+---*/
+
+var regexp = $262.IsHTMLDDA;
+var searcherGets = 0;
+Object.defineProperty(regexp, Symbol.search, {
+ get: function() {
+ searcherGets += 1;
+ return regexp;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".search(regexp), null);
+assert.sameValue(searcherGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/search/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/search/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/search/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/B.2.3.11.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/B.2.3.11.js
new file mode 100644
index 0000000000..52274f8b0a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/B.2.3.11.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.small returns a string of HTML describing a single HTML
+ small print element. The element's content is the `this` value of the
+ function invocation, coerced to a string.
+ es6id: B.2.3.11
+---*/
+
+assert.sameValue('_'.small(), '<small>_</small>');
+assert.sameValue('<'.small(), '<small><</small>');
+assert.sameValue(String.prototype.small.call(0x2A), '<small>42</small>');
+assert.throws(TypeError, function() {
+ String.prototype.small.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.small.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/length.js
new file mode 100644
index 0000000000..0809743f95
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.11
+description: >
+ String.prototype.small.length is 0.
+info: |
+ String.prototype.small ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.small, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/name.js
new file mode 100644
index 0000000000..cc439add06
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.11
+description: >
+ String.prototype.small.name is "small".
+info: |
+ String.prototype.small ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.small, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "small"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/not-a-constructor.js
new file mode 100644
index 0000000000..a0a9aa6090
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.small does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.small),
+ false,
+ 'isConstructor(String.prototype.small) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.small();
+}, '`new String.prototype.small()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/prop-desc.js
new file mode 100644
index 0000000000..631b31349d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.small
+es6id: B.2.3.11
+description: Property descriptor for String.prototype.small
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "small", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/small/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/small/this-val-tostring-err.js
new file mode 100644
index 0000000000..b546cc6ea7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/small/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.small
+es6id: B.2.3.11
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.small.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/split/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/split/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/split/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/split/custom-splitter-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/String/prototype/split/custom-splitter-emulates-undefined.js
new file mode 100644
index 0000000000..fe120958cd
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/split/custom-splitter-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.split
+description: >
+ [[IsHTMLDDA]] object as @@split method gets called.
+info: |
+ String.prototype.split ( separator, limit )
+
+ [...]
+ 2. If separator is neither undefined nor null, then
+ a. Let splitter be ? GetMethod(separator, @@split).
+ b. If splitter is not undefined, then
+ i. Return ? Call(splitter, separator, « O, limit »).
+features: [Symbol.split, IsHTMLDDA]
+---*/
+
+var separator = $262.IsHTMLDDA;
+var splitterGets = 0;
+Object.defineProperty(separator, Symbol.split, {
+ get: function() {
+ splitterGets += 1;
+ return separator;
+ },
+ configurable: true,
+});
+
+assert.sameValue("".split(separator), null);
+assert.sameValue(splitterGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/split/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/split/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/split/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/B.2.3.12.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/B.2.3.12.js
new file mode 100644
index 0000000000..7fef1de75d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/B.2.3.12.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.strike returns a string of HTML describing a single HTML
+ strikethrough element. The element's content is the `this` value of the
+ function invocation, coerced to a string.
+ es6id: B.2.3.12
+---*/
+
+assert.sameValue('_'.strike(), '<strike>_</strike>');
+assert.sameValue('<'.strike(), '<strike><</strike>');
+assert.sameValue(String.prototype.strike.call(0x2A), '<strike>42</strike>');
+assert.throws(TypeError, function() {
+ String.prototype.strike.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.strike.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/length.js
new file mode 100644
index 0000000000..7fc3ac2ff0
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.12
+description: >
+ String.prototype.strike.length is 0.
+info: |
+ String.prototype.strike ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.strike, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/name.js
new file mode 100644
index 0000000000..ed8b2cc4d9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.12
+description: >
+ String.prototype.strike.name is "strike".
+info: |
+ String.prototype.strike ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.strike, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "strike"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/not-a-constructor.js
new file mode 100644
index 0000000000..5f7bc6cbd1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.strike does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.strike),
+ false,
+ 'isConstructor(String.prototype.strike) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.strike();
+}, '`new String.prototype.strike()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/prop-desc.js
new file mode 100644
index 0000000000..61061060d1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.strike
+es6id: B.2.3.12
+description: Property descriptor for String.prototype.strike
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "strike", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/strike/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/this-val-tostring-err.js
new file mode 100644
index 0000000000..77cd44264e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/strike/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.strike
+es6id: B.2.3.12
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.strike.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/B.2.3.13.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/B.2.3.13.js
new file mode 100644
index 0000000000..53f0bcda58
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/B.2.3.13.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.sub returns a string of HTML describing a single HTML
+ subscript element. The element's content is the `this` value of the
+ function invocation, coerced to a string.
+ es6id: B.2.3.13
+---*/
+
+assert.sameValue('_'.sub(), '<sub>_</sub>');
+assert.sameValue('<'.sub(), '<sub><</sub>');
+assert.sameValue(String.prototype.sub.call(0x2A), '<sub>42</sub>');
+assert.throws(TypeError, function() {
+ String.prototype.sub.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.sub.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/length.js
new file mode 100644
index 0000000000..974cc7036a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.13
+description: >
+ String.prototype.sub.length is 0.
+info: |
+ String.prototype.sub ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.sub, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/name.js
new file mode 100644
index 0000000000..4b2ed6a5d4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.13
+description: >
+ String.prototype.sub.name is "sub".
+info: |
+ String.prototype.sub ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.sub, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "sub"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/not-a-constructor.js
new file mode 100644
index 0000000000..3c8b054e9a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/not-a-constructor.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.sub does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(String.prototype.sub), false, 'isConstructor(String.prototype.sub) must return false');
+
+assert.throws(TypeError, () => {
+ new String.prototype.sub();
+}, '`new String.prototype.sub()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/prop-desc.js
new file mode 100644
index 0000000000..775210ff41
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.sub
+es6id: B.2.3.13
+description: Property descriptor for String.prototype.sub
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "sub", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sub/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/this-val-tostring-err.js
new file mode 100644
index 0000000000..1b91b44e57
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sub/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.sub
+es6id: B.2.3.13
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.sub.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/B.2.3.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/B.2.3.js
new file mode 100644
index 0000000000..fb9eb065b8
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/B.2.3.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.3
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (String.prototype.substr)
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "substr", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-falsey.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-falsey.js
new file mode 100644
index 0000000000..3de74fd5cf
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-falsey.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: >
+ Behavior when "length" is a false-converting value other than `undefined`
+info: |
+ [...]
+ 4. If length is undefined, let end be +∞; otherwise let end be ?
+ ToInteger(length).
+ [...]
+ 7. Let resultLength be min(max(end, 0), size - intStart).
+ 8. If resultLength ≤ 0, return the empty String "".
+ 9. Return a String containing resultLength consecutive code units from S
+ beginning with the code unit at index intStart.
+---*/
+
+assert.sameValue('abc'.substr(0, false), '', 'start: 0, length: false');
+assert.sameValue('abc'.substr(1, false), '', 'start: 1, length: false');
+assert.sameValue('abc'.substr(2, false), '', 'start: 2, length: false');
+assert.sameValue('abc'.substr(3, false), '', 'start: 3, length: false');
+
+assert.sameValue('abc'.substr(0, NaN), '', 'start: 0, length: NaN');
+assert.sameValue('abc'.substr(1, NaN), '', 'start: 1, length: NaN');
+assert.sameValue('abc'.substr(2, NaN), '', 'start: 2, length: NaN');
+assert.sameValue('abc'.substr(3, NaN), '', 'start: 3, length: NaN');
+
+assert.sameValue('abc'.substr(0, ''), '', 'start: 0, length: ""');
+assert.sameValue('abc'.substr(1, ''), '', 'start: 1, length: ""');
+assert.sameValue('abc'.substr(2, ''), '', 'start: 2, length: ""');
+assert.sameValue('abc'.substr(3, ''), '', 'start: 3, length: ""');
+
+assert.sameValue('abc'.substr(0, null), '', 'start: 0, length: null');
+assert.sameValue('abc'.substr(1, null), '', 'start: 1, length: null');
+assert.sameValue('abc'.substr(2, null), '', 'start: 2, length: null');
+assert.sameValue('abc'.substr(3, null), '', 'start: 3, length: null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-negative.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-negative.js
new file mode 100644
index 0000000000..48e90b1aac
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-negative.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when "length" is a negative number
+info: |
+ [...]
+ 7. Let resultLength be min(max(end, 0), size - intStart).
+ 8. If resultLength ≤ 0, return the empty String "".
+---*/
+
+assert.sameValue('abc'.substr(0, -1), '', '0, -1');
+assert.sameValue('abc'.substr(0, -2), '', '0, -2');
+assert.sameValue('abc'.substr(0, -3), '', '0, -3');
+assert.sameValue('abc'.substr(0, -4), '', '0, -4');
+
+assert.sameValue('abc'.substr(1, -1), '', '1, -1');
+assert.sameValue('abc'.substr(1, -2), '', '1, -2');
+assert.sameValue('abc'.substr(1, -3), '', '1, -3');
+assert.sameValue('abc'.substr(1, -4), '', '1, -4');
+
+assert.sameValue('abc'.substr(2, -1), '', '2, -1');
+assert.sameValue('abc'.substr(2, -2), '', '2, -2');
+assert.sameValue('abc'.substr(2, -3), '', '2, -3');
+assert.sameValue('abc'.substr(2, -4), '', '2, -4');
+
+assert.sameValue('abc'.substr(3, -1), '', '3, -1');
+assert.sameValue('abc'.substr(3, -2), '', '3, -2');
+assert.sameValue('abc'.substr(3, -3), '', '3, -3');
+assert.sameValue('abc'.substr(3, -4), '', '3, -4');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-positive.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-positive.js
new file mode 100644
index 0000000000..e95b688bd7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-positive.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when "length" is a positive number
+info: |
+ [...]
+ 4. If length is undefined, let end be +∞; otherwise let end be ?
+ ToInteger(length).
+ [...]
+ 7. Let resultLength be min(max(end, 0), size - intStart).
+ 8. If resultLength ≤ 0, return the empty String "".
+ 9. Return a String containing resultLength consecutive code units from S
+ beginning with the code unit at index intStart.
+---*/
+
+assert.sameValue('abc'.substr(0, 1), 'a', '0, 1');
+assert.sameValue('abc'.substr(0, 2), 'ab', '0, 1');
+assert.sameValue('abc'.substr(0, 3), 'abc', '0, 1');
+assert.sameValue('abc'.substr(0, 4), 'abc', '0, 1');
+
+assert.sameValue('abc'.substr(1, 1), 'b', '1, 1');
+assert.sameValue('abc'.substr(1, 2), 'bc', '1, 1');
+assert.sameValue('abc'.substr(1, 3), 'bc', '1, 1');
+assert.sameValue('abc'.substr(1, 4), 'bc', '1, 1');
+
+assert.sameValue('abc'.substr(2, 1), 'c', '2, 1');
+assert.sameValue('abc'.substr(2, 2), 'c', '2, 1');
+assert.sameValue('abc'.substr(2, 3), 'c', '2, 1');
+assert.sameValue('abc'.substr(2, 4), 'c', '2, 1');
+
+assert.sameValue('abc'.substr(3, 1), '', '3, 1');
+assert.sameValue('abc'.substr(3, 2), '', '3, 1');
+assert.sameValue('abc'.substr(3, 3), '', '3, 1');
+assert.sameValue('abc'.substr(3, 4), '', '3, 1');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-to-int-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-to-int-err.js
new file mode 100644
index 0000000000..fe367827b0
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-to-int-err.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-string.prototype.substr
+es6id: B.2.3.1
+description: >
+ Behavior when "length" integer conversion triggers an abrupt completion
+info: |
+ [...]
+ 3. Let intStart be ? ToInteger(start).
+features: [Symbol]
+---*/
+
+var symbol = Symbol('');
+var len = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.substr(0, len);
+});
+
+assert.throws(TypeError, function() {
+ ''.substr(0, symbol);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-undef.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-undef.js
new file mode 100644
index 0000000000..abaee99f0e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length-undef.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when "length" is not defined
+info: |
+ [...]
+ 4. If length is undefined, let end be +∞; otherwise let end be ?
+ ToInteger(length).
+ [...]
+ 7. Let resultLength be min(max(end, 0), size - intStart).
+ 8. If resultLength ≤ 0, return the empty String "".
+ 9. Return a String containing resultLength consecutive code units from S
+ beginning with the code unit at index intStart.
+---*/
+
+assert.sameValue('abc'.substr(0), 'abc', 'start: 0, length: unspecified');
+assert.sameValue('abc'.substr(1), 'bc', 'start: 1, length: unspecified');
+assert.sameValue('abc'.substr(2), 'c', 'start: 2, length: unspecified');
+assert.sameValue('abc'.substr(3), '', 'start: 3, length: unspecified');
+
+assert.sameValue(
+ 'abc'.substr(0, undefined), 'abc', 'start: 0, length: undefined'
+);
+assert.sameValue(
+ 'abc'.substr(1, undefined), 'bc', 'start: 1, length: undefined'
+);
+assert.sameValue(
+ 'abc'.substr(2, undefined), 'c', 'start: 2, length: undefined'
+);
+assert.sameValue(
+ 'abc'.substr(3, undefined), '', 'start: 3, length: undefined'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length.js
new file mode 100644
index 0000000000..93654798c4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.1
+description: >
+ String.prototype.substr.length is 2.
+info: |
+ String.prototype.substr (start, length)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.substr, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 2
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/name.js
new file mode 100644
index 0000000000..d9b3306250
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.1
+description: >
+ String.prototype.substr.name is "substr".
+info: |
+ String.prototype.substr (start, length)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.substr, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "substr"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/not-a-constructor.js
new file mode 100644
index 0000000000..821d6473a4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/not-a-constructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.substr does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(String.prototype.substr),
+ false,
+ 'isConstructor(String.prototype.substr) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new String.prototype.substr();
+}, '`new String.prototype.substr()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-and-length-as-numbers.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-and-length-as-numbers.js
new file mode 100644
index 0000000000..0b0df5427a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-and-length-as-numbers.js
@@ -0,0 +1,94 @@
+// Copyright (C) 2022 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.substr
+description: >
+ Test String.prototype.substr with number inputs for start and length.
+---*/
+
+function ToIntegerOrInfinity(arg) {
+ assert.sameValue(typeof arg, "number");
+
+ return Number.isNaN(arg) ? 0 : Math.trunc(arg);
+}
+
+// Basic reference implementation. Expects all inputs have the correct type.
+function StringSubstr(string, start, length) {
+ // Steps 1-2.
+ assert.sameValue(typeof string, "string");
+
+ // Step 3.
+ let size = string.length;
+
+ // Step 4.
+ let intStart = ToIntegerOrInfinity(start);
+
+ // Steps 5-7.
+ if (intStart === -Infinity) {
+ intStart = 0;
+ } else if (intStart < 0) {
+ intStart = Math.max(size + intStart, 0);
+ } else {
+ intStart = Math.min(intStart, size)
+ }
+
+ // |0 <= intStart <= size| now holds.
+ assert(0 <= intStart && intStart <= size);
+
+ // Step 8.
+ let intLength = length === undefined ? size : ToIntegerOrInfinity(length);
+
+ // Step 9.
+ intLength = Math.min(Math.max(intLength, 0), size);
+
+ // |0 <= intLength <= size| now holds.
+ assert(0 <= intLength && intLength <= size);
+
+ // Step 10.
+ let intEnd = Math.min(intStart + intLength, size);
+
+ // |intStart <= intEnd <= size| now holds.
+ assert(intStart <= intEnd && intEnd <= size);
+
+ // Step 11.
+ //
+ // Call `substring` and check the result is correct.
+ let result = string.substring(intStart, intEnd);
+
+ assert.sameValue(result.length, intEnd - intStart);
+
+ for (let i = 0; i < result.length; ++i) {
+ assert.sameValue(result[i], string[intStart + i]);
+ }
+
+ return result;
+}
+
+const positiveIntegers = [
+ 0, 1, 2, 3, 4, 5, 10, 100,
+];
+
+const integers = [
+ ...positiveIntegers,
+ ...positiveIntegers.map(v => -v),
+];
+
+const numbers = [
+ ...integers,
+ ...integers.map(v => v + 0.5),
+ -Infinity, Infinity, NaN,
+];
+
+for (let string of ["", "a", "ab", "abc"]) {
+ for (let start of numbers) {
+ for (let length of [...numbers, undefined]) {
+ let actual = string.substr(start, length);
+ let expected = StringSubstr(string, start, length);
+
+ assert.sameValue(actual, expected, `"${string}".substr(${start}, ${length})`);
+ }
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-negative.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-negative.js
new file mode 100644
index 0000000000..de56b29e68
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-negative.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when "start" is a negative number
+info: |
+ [...]
+ 6. If intStart < 0, let intStart be max(size + intStart, 0).
+---*/
+
+assert.sameValue('abc'.substr(-1), 'c');
+assert.sameValue('abc'.substr(-2), 'bc');
+assert.sameValue('abc'.substr(-3), 'abc');
+assert.sameValue('abc'.substr(-4), 'abc', 'size + intStart < 0');
+
+assert.sameValue('abc'.substr(-1.1), 'c', 'floating point rounding semantics');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-to-int-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-to-int-err.js
new file mode 100644
index 0000000000..4511de91ba
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/start-to-int-err.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: >
+ Behavior when "start" integer conversion triggers an abrupt completion
+info: |
+ [...]
+ 3. Let intStart be ? ToInteger(start).
+features: [Symbol]
+---*/
+
+var lengthCallCount = 0;
+var symbol = Symbol('');
+var start = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+var len = {
+ valueOf: function() {
+ lengthCallCount += 1;
+ }
+};
+
+assert.throws(Test262Error, function() {
+ ''.substr(start, len);
+});
+
+assert.throws(TypeError, function() {
+ ''.substr(symbol, len);
+});
+
+assert.sameValue(lengthCallCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/surrogate-pairs.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/surrogate-pairs.js
new file mode 100644
index 0000000000..605596d335
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/surrogate-pairs.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: >
+ Behavior when input string contains a surrogate pair
+info: |
+ [...]
+ 4. If length is undefined, let end be +∞; otherwise let end be ?
+ ToInteger(length).
+ [...]
+ 7. Let resultLength be min(max(end, 0), size - intStart).
+ 8. If resultLength ≤ 0, return the empty String "".
+ 9. Return a String containing resultLength consecutive code units from S
+ beginning with the code unit at index intStart.
+---*/
+
+assert.sameValue('\ud834\udf06'.substr(0), '\ud834\udf06', 'start: 0');
+assert.sameValue('\ud834\udf06'.substr(1), '\udf06', 'start: 1');
+assert.sameValue('\ud834\udf06'.substr(2), '', 'start: 2');
+assert.sameValue('\ud834\udf06'.substr(0, 0), '', 'end: 0');
+assert.sameValue('\ud834\udf06'.substr(0, 1), '\ud834', 'end: 1');
+assert.sameValue('\ud834\udf06'.substr(0, 2), '\ud834\udf06', 'end: 2');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-non-obj-coerce.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-non-obj-coerce.js
new file mode 100644
index 0000000000..7036c9e250
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-non-obj-coerce.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when "this" value is not Object-coercible
+info: |
+ 1. Let O be ? RequireObjectCoercible(this value).
+---*/
+
+var substr = String.prototype.substr;
+
+assert.sameValue(typeof substr, 'function');
+
+assert.throws(TypeError, function() {
+ substr.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ substr.call(null);
+}, 'null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-to-str-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-to-str-err.js
new file mode 100644
index 0000000000..669f572a04
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/substr/this-to-str-err.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.substr
+es6id: B.2.3.1
+description: Behavior when string conversion triggers an abrupt completion
+info: |
+ 1. Let O be ? RequireObjectCoercible(this value).
+ 2. Let S be ? ToString(O).
+---*/
+
+var substr = String.prototype.substr;
+var thisValue = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ substr.call(thisValue);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/B.2.3.14.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/B.2.3.14.js
new file mode 100644
index 0000000000..a54131b658
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/B.2.3.14.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// Tests taken from:
+// http://mathias.html5.org/tests/javascript/string/
+
+/*---
+ description: >
+ String.prototype.sup returns a string of HTML describing a single HTML
+ superscript element. The element's content is the `this` value of the
+ function invocation, coerced to a string.
+ es6id: B.2.3.14
+---*/
+
+assert.sameValue('_'.sup(), '<sup>_</sup>');
+assert.sameValue('<'.sup(), '<sup><</sup>');
+assert.sameValue(String.prototype.sup.call(0x2A), '<sup>42</sup>');
+assert.throws(TypeError, function() {
+ String.prototype.sup.call(undefined);
+});
+assert.throws(TypeError, function() {
+ String.prototype.sup.call(null);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/length.js
new file mode 100644
index 0000000000..d05dc61b42
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.14
+description: >
+ String.prototype.sup.length is 0.
+info: |
+ String.prototype.sup ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.sup, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 0
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/name.js
new file mode 100644
index 0000000000..054d5484ef
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.3.14
+description: >
+ String.prototype.sup.name is "sup".
+info: |
+ String.prototype.sup ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype.sup, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "sup"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/not-a-constructor.js
new file mode 100644
index 0000000000..461a34d60e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/not-a-constructor.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ String.prototype.sup does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(String.prototype.sup), false, 'isConstructor(String.prototype.sup) must return false');
+
+assert.throws(TypeError, () => {
+ new String.prototype.sup();
+}, '`new String.prototype.sup()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/prop-desc.js
new file mode 100644
index 0000000000..c22448d3fb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/prop-desc.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.sup
+es6id: B.2.3.14
+description: Property descriptor for String.prototype.sup
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(String.prototype, "sup", {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/sup/this-val-tostring-err.js b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/this-val-tostring-err.js
new file mode 100644
index 0000000000..ef2669921f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/sup/this-val-tostring-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-string.prototype.sup
+es6id: B.2.3.14
+description: Abrupt completion when coercing "this" value to string
+info: |
+ B.2.3.2.1 Runtime Semantics: CreateHTML
+
+ 1. Let str be ? RequireObjectCoercible(string).
+ 2. Let S be ? ToString(str).
+---*/
+
+var thisVal = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ String.prototype.sup.call(thisVal);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/length.js
new file mode 100644
index 0000000000..76d4b87fc5
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+ String.prototype.trimLeft.length is 0.
+info: >
+ String.prototype.trimLeft ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype.trimLeft, "length", {
+ value: 0,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/name.js
new file mode 100644
index 0000000000..277da5d95f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/name.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+ String.prototype.trimLeft.name is "trimStart".
+info: >
+ String.prototype.trimLeft ( )
+
+ The function object that is the initial value of String.prototype.trimLeft is the same function object that is the initial value of String.prototype.trimStart.
+
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+verifyProperty(String.prototype.trimLeft, "name", {
+ value: "trimStart",
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/prop-desc.js
new file mode 100644
index 0000000000..f1589dbacc
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+ "trimLeft" property of String.prototype
+info: >
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2
+ has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype, "trimLeft", {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/reference-trimStart.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/reference-trimStart.js
new file mode 100644
index 0000000000..d9c709aff1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/reference-trimStart.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+ String.prototype.trimLeft is a reference to String.prototype.trimStart.
+info: >
+ String.prototype.trimLeft ( )
+
+ The function object that is the initial value of String.prototype.trimLeft
+ is the same function object that is the initial value of
+ String.prototype.trimStart.
+features: [string-trimming]
+---*/
+
+assert.sameValue(String.prototype.trimLeft, String.prototype.trimStart);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/browser.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/length.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/length.js
new file mode 100644
index 0000000000..53ece40072
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+ String.prototype.trimRight.length is 0.
+info: >
+ String.prototype.trimRight ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype.trimRight, "length", {
+ value: 0,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/name.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/name.js
new file mode 100644
index 0000000000..43f7b94849
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/name.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+ String.prototype.trimRight.name is "trimEnd".
+info: >
+ String.prototype.trimRight ( )#
+
+ The function object that is the initial value of String.prototype.trimRight is the same function object that is the initial value of String.prototype.trimEnd.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+verifyProperty(String.prototype.trimRight, "name", {
+ value: "trimEnd",
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/prop-desc.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/prop-desc.js
new file mode 100644
index 0000000000..a2b1e52c90
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+ "trimRight" property of String.prototype
+info: >
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2
+ has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype, "trimRight", {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/reference-trimEnd.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/reference-trimEnd.js
new file mode 100644
index 0000000000..23a375af15
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/reference-trimEnd.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+ String.prototype.trimRight is a reference to String.prototype.trimEnd.
+info: >
+ String.prototype.trimRight ( )
+
+ The function object that is the initial value of String.prototype.trimRight
+ is the same function object that is the initial value of
+ String.prototype.trimEnd.
+features: [string-trimming]
+---*/
+
+assert.sameValue(String.prototype.trimRight, String.prototype.trimEnd);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/shell.js b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/String/shell.js b/js/src/tests/test262/annexB/built-ins/String/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/browser.js b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/browser.js b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/iterator-method-emulates-undefined.js b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/iterator-method-emulates-undefined.js
new file mode 100644
index 0000000000..5e41a374eb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/iterator-method-emulates-undefined.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-%typedarray%.from
+description: >
+ [[IsHTMLDDA]] object as @@iterator method gets called.
+info: |
+ %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
+
+ [...]
+ 5. Let usingIterator be ? GetMethod(items, @@iterator).
+ 6. If usingIterator is not undefined, then
+ a. Let values be ? IterableToList(source, usingIterator).
+
+ IterableToList ( items, method )
+
+ 1. Let iteratorRecord be ? GetIterator(items, sync, method).
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ [...]
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+includes: [testTypedArray.js]
+features: [Symbol.iterator, TypedArray, IsHTMLDDA]
+---*/
+
+var items = {};
+items[Symbol.iterator] = $262.IsHTMLDDA;
+
+testWithTypedArrayConstructors(function(TypedArray) {
+ assert.throws(TypeError, function() {
+ TypedArray.from(items);
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/shell.js b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/shell.js
new file mode 100644
index 0000000000..e9580b3113
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/from/shell.js
@@ -0,0 +1,124 @@
+// GENERATED, DO NOT EDIT
+// file: testTypedArray.js
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of functions used to assert the correctness of TypedArray objects.
+defines:
+ - typedArrayConstructors
+ - floatArrayConstructors
+ - intArrayConstructors
+ - TypedArray
+ - testWithTypedArrayConstructors
+ - testWithAtomicsFriendlyTypedArrayConstructors
+ - testWithNonAtomicsFriendlyTypedArrayConstructors
+ - testTypedArrayConversions
+---*/
+
+/**
+ * Array containing every typed array constructor.
+ */
+var typedArrayConstructors = [
+ Float64Array,
+ Float32Array,
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array,
+ Uint8ClampedArray
+];
+
+var floatArrayConstructors = typedArrayConstructors.slice(0, 2);
+var intArrayConstructors = typedArrayConstructors.slice(2, 7);
+
+/**
+ * The %TypedArray% intrinsic constructor function.
+ */
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+/**
+ * Callback for testing a typed array constructor.
+ *
+ * @callback typedArrayConstructorCallback
+ * @param {Function} Constructor the constructor object to test with.
+ */
+
+/**
+ * Calls the provided function for every typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithTypedArrayConstructors(f, selected) {
+ var constructors = selected || typedArrayConstructors;
+ for (var i = 0; i < constructors.length; ++i) {
+ var constructor = constructors[i];
+ try {
+ f(constructor);
+ } catch (e) {
+ e.message += " (Testing with " + constructor.name + ".)";
+ throw e;
+ }
+ }
+}
+
+/**
+ * Calls the provided function for every non-"Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithNonAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, [
+ Float64Array,
+ Float32Array,
+ Uint8ClampedArray
+ ]);
+}
+
+/**
+ * Calls the provided function for every "Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, [
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array,
+ ]);
+}
+
+/**
+ * Helper for conversion operations on TypedArrays, the expected values
+ * properties are indexed in order to match the respective value for each
+ * TypedArray constructor
+ * @param {Function} fn - the function to call for each constructor and value.
+ * will be called with the constructor, value, expected
+ * value, and a initial value that can be used to avoid
+ * a false positive with an equivalent expected value.
+ */
+function testTypedArrayConversions(byteConversionValues, fn) {
+ var values = byteConversionValues.values;
+ var expected = byteConversionValues.expected;
+
+ testWithTypedArrayConstructors(function(TA) {
+ var name = TA.name.slice(0, -5);
+
+ return values.forEach(function(value, index) {
+ var exp = expected[name][index];
+ var initial = 0;
+ if (exp === 0) {
+ initial = 1;
+ }
+ fn(TA, value, exp, initial);
+ });
+ });
+}
diff --git a/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/shell.js b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/TypedArrayConstructors/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/browser.js b/js/src/tests/test262/annexB/built-ins/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/escape/argument_bigint.js b/js/src/tests/test262/annexB/built-ins/escape/argument_bigint.js
new file mode 100644
index 0000000000..20a0340cce
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/argument_bigint.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+description: Input is a BigInt
+info: |
+ B.2.1.1 escape ( string )
+
+ 1. Let string be ? ToString(string).
+ ...
+features: [BigInt]
+---*/
+
+assert.sameValue(escape(1n), '1');
+
+assert.sameValue(escape(-1n), '-1');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/argument_types.js b/js/src/tests/test262/annexB/built-ins/escape/argument_types.js
new file mode 100644
index 0000000000..cb04677445
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/argument_types.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+description: Input is a null, undefined, boolean or Number
+info: |
+ B.2.1.1 escape ( string )
+
+ 1. Let string be ? ToString(string).
+ ...
+---*/
+
+assert.sameValue(escape(null), 'null');
+
+assert.sameValue(escape(undefined), 'undefined');
+
+assert.sameValue(escape(), 'undefined');
+
+assert.sameValue(escape(true), 'true');
+
+assert.sameValue(escape(false), 'false');
+
+assert.sameValue(escape(-0), '0');
+
+assert.sameValue(escape(0), '0');
+
+assert.sameValue(escape(1), '1');
+
+assert.sameValue(escape(NaN), 'NaN');
+
+assert.sameValue(escape(Number.POSITIVE_INFINITY), 'Infinity');
+
+assert.sameValue(escape(Number.NEGATIVE_INFINITY), '-Infinity');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/browser.js b/js/src/tests/test262/annexB/built-ins/escape/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/escape/empty-string.js b/js/src/tests/test262/annexB/built-ins/escape/empty-string.js
new file mode 100644
index 0000000000..65143c90d1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/empty-string.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Input is the empty string
+info: |
+ 1. Let string be ? ToString(string).
+ 2. Let length be the number of code units in string.
+ 3. Let R be the empty string.
+ 4. Let k be 0.
+ 5. Repeat, while k < length,
+ [...]
+ 6. Return R.
+---*/
+
+assert.sameValue(escape(''), '');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/escape-above-astral.js b/js/src/tests/test262/annexB/built-ins/escape/escape-above-astral.js
new file mode 100644
index 0000000000..7ab8e7ed0d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/escape-above-astral.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 Microsoft Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Escaping of code units above 255 from string with extended Unicode escape sequence
+info: |
+ [...]
+ 5. Repeat, while k < length,
+ a. Let char be the code unit (represented as a 16-bit unsigned integer)
+ at index k within string.
+ [...]
+ c. Else if char ≥ 256, then
+ i. Let S be a String containing six code units "%uwxyz" where wxyz
+ are the code units of the four uppercase hexadecimal digits
+ encoding the value of char.
+ [...]
+---*/
+
+assert.sameValue(
+ escape('\u{10401}'), '%uD801%uDC01', '\\u{10401} => \\uD801\\uDC01 (surrogate pairs encoded in string)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/escape-above.js b/js/src/tests/test262/annexB/built-ins/escape/escape-above.js
new file mode 100644
index 0000000000..347530476e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/escape-above.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Escaping of code units above 255
+info: |
+ [...]
+ 5. Repeat, while k < length,
+ a. Let char be the code unit (represented as a 16-bit unsigned integer)
+ at index k within string.
+ [...]
+ c. Else if char ≥ 256, then
+ i. Let S be a String containing six code units "%uwxyz" where wxyz
+ are the code units of the four uppercase hexadecimal digits
+ encoding the value of char.
+ [...]
+---*/
+
+assert.sameValue(
+ escape('\u0100\u0101\u0102'), '%u0100%u0101%u0102', '\\u0100\\u0101\\u0102'
+);
+
+assert.sameValue(
+ escape('\ufffd\ufffe\uffff'), '%uFFFD%uFFFE%uFFFF', '\\ufffd\\ufffd\\ufffd'
+);
+
+assert.sameValue(
+ escape('\ud834\udf06'), '%uD834%uDF06', '\\ud834\\udf06 (surrogate pairs)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/escape-below.js b/js/src/tests/test262/annexB/built-ins/escape/escape-below.js
new file mode 100644
index 0000000000..197fcf70e8
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/escape-below.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Escaping of code units below 255
+info: |
+ [...]
+ 5. Repeat, while k < length,
+ a. Let char be the code unit (represented as a 16-bit unsigned integer)
+ at index k within string.
+ [...]
+ d. Else char < 256,
+ i. Let S be a String containing three code units "%xy" where xy are
+ the code units of two uppercase hexadecimal digits encoding the
+ value of char.
+ [...]
+---*/
+
+assert.sameValue(
+ escape('\x00\x01\x02\x03'),
+ '%00%01%02%03',
+ 'characters: \\x00\\x01\\x02\\x03'
+);
+
+assert.sameValue(
+ escape('!"#$%&\'()'),
+ '%21%22%23%24%25%26%27%28%29',
+ 'characters preceding "*": !"#$%&\'()'
+);
+
+assert.sameValue(escape(','), '%2C', 'character between "+" and "-": ,');
+
+assert.sameValue(
+ escape(':;<=>?'),
+ '%3A%3B%3C%3D%3E%3F',
+ 'characters between "9" and "@": :;<=>?'
+);
+
+assert.sameValue(
+ escape('[\\]^'), '%5B%5C%5D%5E', 'characters between "Z" and "_": [\\]^'
+);
+
+assert.sameValue(escape('`'), '%60', 'character between "_" and "a": `');
+
+assert.sameValue(
+ escape('{|}~\x7f\x80'),
+ '%7B%7C%7D%7E%7F%80',
+ 'characters following "z": {|}~\\x7f\\x80'
+);
+
+assert.sameValue(
+ escape('\xfd\xfe\xff'), '%FD%FE%FF', '\\xfd\\xfe\\xff'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/length.js b/js/src/tests/test262/annexB/built-ins/escape/length.js
new file mode 100644
index 0000000000..6d8c672f6e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.1.1
+description: >
+ escape.length is 1.
+info: |
+ escape (string)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(escape, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/name.js b/js/src/tests/test262/annexB/built-ins/escape/name.js
new file mode 100644
index 0000000000..6a3cf986a1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.1.1
+description: >
+ escape.name is "escape".
+info: |
+ escape (string)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(escape, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "escape"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/escape/not-a-constructor.js
new file mode 100644
index 0000000000..9fd1e0deb7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/not-a-constructor.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ escape does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(escape), false, 'isConstructor(escape) must return false');
+
+assert.throws(TypeError, () => {
+ new escape('');
+}, '`new escape(\'\')` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/prop-desc.js b/js/src/tests/test262/annexB/built-ins/escape/prop-desc.js
new file mode 100644
index 0000000000..6669166aae
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.1
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (Global.escape)
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof this.escape, "function");
+assert.sameValue(typeof this["escape"], "function");
+
+verifyProperty(this, "escape", {
+ writable: true,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/shell.js b/js/src/tests/test262/annexB/built-ins/escape/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/escape/to-primitive-err.js b/js/src/tests/test262/annexB/built-ins/escape/to-primitive-err.js
new file mode 100644
index 0000000000..b172fe2b28
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/to-primitive-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+description: If [Symbol.toPrimitive] method returned an object, it should throw a TypeError
+info: |
+ B.2.1.1 escape ( string )
+
+ 1. Let string be ? ToString(string).
+ ...
+features: [Symbol.toPrimitive]
+---*/
+
+var obj = {
+ toString() { throw new Test262Error('this should be unreachable'); },
+ valueOf() { throw new Test262Error('this should be unreachable'); },
+ [Symbol.toPrimitive]() { return function(){}; }
+};
+
+assert.throws(TypeError, function() {
+ escape(obj);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/to-primitive-observe.js b/js/src/tests/test262/annexB/built-ins/escape/to-primitive-observe.js
new file mode 100644
index 0000000000..4b0cc7935c
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/to-primitive-observe.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+description: Observable operations from string coercion
+info: |
+ B.2.1.1 escape ( string )
+
+ 1. Let string be ? ToString(string).
+ ...
+features: [Symbol.toPrimitive]
+---*/
+
+var obj = {
+ toString() { throw new Test262Error('this should be unreachable'); },
+ valueOf() { throw new Test262Error('this should be unreachable'); },
+ [Symbol.toPrimitive]() { return 'success'; }
+};
+
+assert.sameValue(escape(obj), 'success');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/to-string-err-symbol.js b/js/src/tests/test262/annexB/built-ins/escape/to-string-err-symbol.js
new file mode 100644
index 0000000000..6cd2663e3f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/to-string-err-symbol.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Abrupt completion from `ToString` operation (Symbol value)
+info: |
+ 1. Let string be ? ToString(string).
+features: [Symbol]
+---*/
+
+var s = Symbol('');
+
+assert.throws(TypeError, function() {
+ escape(s);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/to-string-err.js b/js/src/tests/test262/annexB/built-ins/escape/to-string-err.js
new file mode 100644
index 0000000000..5d5aaa8b2f
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/to-string-err.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Abrupt completion from `ToString` operation
+info: |
+ 1. Let string be ? ToString(string).
+---*/
+
+var obj = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ escape(obj);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/to-string-observe.js b/js/src/tests/test262/annexB/built-ins/escape/to-string-observe.js
new file mode 100644
index 0000000000..c9dcd49f99
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/to-string-observe.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Observable operations from string coercion
+info: |
+ 1. Let string be ? ToString(string).
+---*/
+
+var log, obj;
+
+log = '';
+obj = {
+ toString: function() {
+ log += 'toString';
+ },
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+escape(obj);
+
+assert.sameValue(log, 'toString');
+
+log = '';
+obj = {
+ toString: null,
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+escape(obj);
+
+assert.sameValue(log, 'valueOf');
+
+log = '';
+obj = {
+ toString: function() {
+ log += 'toString';
+ return {};
+ },
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+escape(obj);
+
+assert.sameValue(log, 'toStringvalueOf');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/escape/unmodified.js b/js/src/tests/test262/annexB/built-ins/escape/unmodified.js
new file mode 100644
index 0000000000..0f8e82c4ae
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/escape/unmodified.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-escape-string
+es6id: B.2.1.1
+description: Do not escape a specific set of characters
+info: |
+ [...]
+ 5. Repeat, while k < length,
+ a. Let char be the code unit (represented as a 16-bit unsigned integer)
+ at index k within string.
+ b. If char is one of the code units in
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./",
+ then
+ i. Let S be a String containing the single code unit char.
+ [...]
+---*/
+
+var passthrough = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./';
+
+assert.sameValue(escape(passthrough), passthrough);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/shell.js b/js/src/tests/test262/annexB/built-ins/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/shell.js
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/argument_bigint.js b/js/src/tests/test262/annexB/built-ins/unescape/argument_bigint.js
new file mode 100644
index 0000000000..00f17cb5e7
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/argument_bigint.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+description: Input is a BigInt
+info: |
+ B.2.1.2 unescape ( string )
+
+ 1. Set string to ? ToString(string).
+ ....
+features: [BigInt]
+---*/
+
+assert.sameValue(unescape(1n), '1');
+
+assert.sameValue(unescape(-1n), '-1');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/argument_types.js b/js/src/tests/test262/annexB/built-ins/unescape/argument_types.js
new file mode 100644
index 0000000000..008e1a1bdb
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/argument_types.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+description: Input is a null, undefined, boolean or Number
+info: |
+ B.2.1.2 unescape ( string )
+
+ 1. Set string to ? ToString(string).
+ ...
+---*/
+
+assert.sameValue(unescape(null), 'null');
+
+assert.sameValue(unescape(undefined), 'undefined');
+
+assert.sameValue(unescape(), 'undefined');
+
+assert.sameValue(unescape(true), 'true');
+
+assert.sameValue(unescape(false), 'false');
+
+assert.sameValue(unescape(-0), '0');
+
+assert.sameValue(unescape(0), '0');
+
+assert.sameValue(unescape(1), '1');
+
+assert.sameValue(unescape(NaN), 'NaN');
+
+assert.sameValue(unescape(Number.POSITIVE_INFINITY), 'Infinity');
+
+assert.sameValue(unescape(Number.NEGATIVE_INFINITY), '-Infinity');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/browser.js b/js/src/tests/test262/annexB/built-ins/unescape/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/browser.js
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/empty-string.js b/js/src/tests/test262/annexB/built-ins/unescape/empty-string.js
new file mode 100644
index 0000000000..41c491239e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/empty-string.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Input is the empty string
+info: |
+ 1. Let string be ? ToString(string).
+ 2. Let length be the number of code units in string.
+ 3. Let R be the empty string.
+ 4. Let k be 0.
+ 5. Repeat, while k ≠ length,
+ [...]
+ 6. Return R.
+---*/
+
+assert.sameValue(unescape(''), '');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-bad-u.js b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-bad-u.js
new file mode 100644
index 0000000000..09b9fd30f3
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-bad-u.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: >
+ Does not transform four-character patterns that are not prefixed with the
+ character "u"
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ i. If k ≤ length-6 and the code unit at index k+1 within string is u
+ and the four code units at indices k+2, k+3, k+4, and k+5 within
+ string are all hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by the four hexadecimal digits at indices k+2, k+3, k+4, and
+ k+5 within string.
+ 2. Increase k by 5.
+ [...]
+---*/
+
+assert.sameValue(unescape('%U0000'), '%U0000');
+assert.sameValue(unescape('%t0000'), '%t0000');
+assert.sameValue(unescape('%v0000'), '%v0000');
+assert.sameValue(unescape('%%0000'), '%\x0000');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-end-str.js b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-end-str.js
new file mode 100644
index 0000000000..da1a016bc4
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-end-str.js
@@ -0,0 +1,96 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: >
+ Does not transform four-character patterns that are interrupted by the end
+ of the string
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ i. If k ≤ length-6 and the code unit at index k+1 within string is u
+ and the four code units at indices k+2, k+3, k+4, and k+5 within
+ string are all hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by the four hexadecimal digits at indices k+2, k+3, k+4, and
+ k+5 within string.
+ 2. Increase k by 5.
+ [...]
+---*/
+
+assert.sameValue(unescape('%u'), '%u');
+
+assert.sameValue(unescape('%u0'), '%u0');
+assert.sameValue(unescape('%u1'), '%u1');
+assert.sameValue(unescape('%u2'), '%u2');
+assert.sameValue(unescape('%u3'), '%u3');
+assert.sameValue(unescape('%u4'), '%u4');
+assert.sameValue(unescape('%u5'), '%u5');
+assert.sameValue(unescape('%u6'), '%u6');
+assert.sameValue(unescape('%u7'), '%u7');
+assert.sameValue(unescape('%u8'), '%u8');
+assert.sameValue(unescape('%u9'), '%u9');
+assert.sameValue(unescape('%ua'), '%ua');
+assert.sameValue(unescape('%uA'), '%uA');
+assert.sameValue(unescape('%ub'), '%ub');
+assert.sameValue(unescape('%uB'), '%uB');
+assert.sameValue(unescape('%uc'), '%uc');
+assert.sameValue(unescape('%uC'), '%uC');
+assert.sameValue(unescape('%ud'), '%ud');
+assert.sameValue(unescape('%uD'), '%uD');
+assert.sameValue(unescape('%ue'), '%ue');
+assert.sameValue(unescape('%uE'), '%uE');
+assert.sameValue(unescape('%uf'), '%uf');
+assert.sameValue(unescape('%uF'), '%uF');
+
+assert.sameValue(unescape('%u00'), '%u00');
+assert.sameValue(unescape('%u01'), '%u01');
+assert.sameValue(unescape('%u02'), '%u02');
+assert.sameValue(unescape('%u03'), '%u03');
+assert.sameValue(unescape('%u04'), '%u04');
+assert.sameValue(unescape('%u05'), '%u05');
+assert.sameValue(unescape('%u06'), '%u06');
+assert.sameValue(unescape('%u07'), '%u07');
+assert.sameValue(unescape('%u08'), '%u08');
+assert.sameValue(unescape('%u09'), '%u09');
+assert.sameValue(unescape('%u0a'), '%u0a');
+assert.sameValue(unescape('%u0A'), '%u0A');
+assert.sameValue(unescape('%u0b'), '%u0b');
+assert.sameValue(unescape('%u0B'), '%u0B');
+assert.sameValue(unescape('%u0c'), '%u0c');
+assert.sameValue(unescape('%u0C'), '%u0C');
+assert.sameValue(unescape('%u0d'), '%u0d');
+assert.sameValue(unescape('%u0D'), '%u0D');
+assert.sameValue(unescape('%u0e'), '%u0e');
+assert.sameValue(unescape('%u0E'), '%u0E');
+assert.sameValue(unescape('%u0f'), '%u0f');
+assert.sameValue(unescape('%u0F'), '%u0F');
+
+assert.sameValue(unescape('%u000'), '%u000');
+assert.sameValue(unescape('%u001'), '%u001');
+assert.sameValue(unescape('%u002'), '%u002');
+assert.sameValue(unescape('%u003'), '%u003');
+assert.sameValue(unescape('%u004'), '%u004');
+assert.sameValue(unescape('%u005'), '%u005');
+assert.sameValue(unescape('%u006'), '%u006');
+assert.sameValue(unescape('%u007'), '%u007');
+assert.sameValue(unescape('%u008'), '%u008');
+assert.sameValue(unescape('%u009'), '%u009');
+assert.sameValue(unescape('%u00a'), '%u00a');
+assert.sameValue(unescape('%u00A'), '%u00A');
+assert.sameValue(unescape('%u00b'), '%u00b');
+assert.sameValue(unescape('%u00B'), '%u00B');
+assert.sameValue(unescape('%u00c'), '%u00c');
+assert.sameValue(unescape('%u00C'), '%u00C');
+assert.sameValue(unescape('%u00d'), '%u00d');
+assert.sameValue(unescape('%u00D'), '%u00D');
+assert.sameValue(unescape('%u00e'), '%u00e');
+assert.sameValue(unescape('%u00E'), '%u00E');
+assert.sameValue(unescape('%u00f'), '%u00f');
+assert.sameValue(unescape('%u00F'), '%u00F');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-non-hex.js b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-non-hex.js
new file mode 100644
index 0000000000..411a62c551
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/four-ignore-non-hex.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: >
+ Does not transform four-character patterns that contain non-hexadecimal
+ digits
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ i. If k ≤ length-6 and the code unit at index k+1 within string is u
+ and the four code units at indices k+2, k+3, k+4, and k+5 within
+ string are all hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by the four hexadecimal digits at indices k+2, k+3, k+4, and
+ k+5 within string.
+ 2. Increase k by 5.
+ [...]
+---*/
+
+assert.sameValue(unescape('%u000%0'), '%u000%0');
+
+assert.sameValue(unescape('%u000g0'), '%u000g0');
+assert.sameValue(unescape('%u000G0'), '%u000G0');
+assert.sameValue(unescape('%u00g00'), '%u00g00');
+assert.sameValue(unescape('%u00G00'), '%u00G00');
+assert.sameValue(unescape('%u0g000'), '%u0g000');
+assert.sameValue(unescape('%u0G000'), '%u0G000');
+assert.sameValue(unescape('%ug0000'), '%ug0000');
+assert.sameValue(unescape('%uG0000'), '%uG0000');
+
+assert.sameValue(unescape('%u000u0'), '%u000u0');
+assert.sameValue(unescape('%u000U0'), '%u000U0');
+assert.sameValue(unescape('%u00u00'), '%u00u00');
+assert.sameValue(unescape('%u00U00'), '%u00U00');
+assert.sameValue(unescape('%u0u000'), '%u0u000');
+assert.sameValue(unescape('%u0U000'), '%u0U000');
+assert.sameValue(unescape('%uu0000'), '%uu0000');
+assert.sameValue(unescape('%uU0000'), '%uU0000');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/four.js b/js/src/tests/test262/annexB/built-ins/unescape/four.js
new file mode 100644
index 0000000000..35aeb4f74e
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/four.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Translation of patterns with four digits
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ i. If k ≤ length-6 and the code unit at index k+1 within string is u
+ and the four code units at indices k+2, k+3, k+4, and k+5 within
+ string are all hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by the four hexadecimal digits at indices k+2, k+3, k+4, and
+ k+5 within string.
+ 2. Increase k by 5.
+ [...]
+---*/
+
+assert.sameValue(unescape('%0%u00000'), '%0\x000', '%u0000');
+assert.sameValue(unescape('%0%u00010'), '%0\x010', '%u0001');
+
+assert.sameValue(unescape('%0%u00290'), '%0)0', '%002900');
+assert.sameValue(unescape('%0%u002a0'), '%0*0', '%002a00');
+assert.sameValue(unescape('%0%u002A0'), '%0*0', '%002A00');
+assert.sameValue(unescape('%0%u002b0'), '%0+0', '%002b00');
+assert.sameValue(unescape('%0%u002B0'), '%0+0', '%002B00');
+assert.sameValue(unescape('%0%u002c0'), '%0,0', '%002c00');
+assert.sameValue(unescape('%0%u002C0'), '%0,0', '%002C00');
+assert.sameValue(unescape('%0%u002d0'), '%0-0', '%002d00');
+assert.sameValue(unescape('%0%u002D0'), '%0-0', '%002D00');
+
+assert.sameValue(unescape('%0%u00390'), '%090', '%003900');
+assert.sameValue(unescape('%0%u003a0'), '%0:0', '%003A00');
+assert.sameValue(unescape('%0%u003A0'), '%0:0', '%003A00');
+
+assert.sameValue(unescape('%0%u003f0'), '%0?0', '%003f00');
+assert.sameValue(unescape('%0%u003F0'), '%0?0', '%003F00');
+assert.sameValue(unescape('%0%u00400'), '%0@0', '%004000');
+
+assert.sameValue(unescape('%0%u005a0'), '%0Z0', '%005a00');
+assert.sameValue(unescape('%0%u005A0'), '%0Z0', '%005A00');
+assert.sameValue(unescape('%0%u005b0'), '%0[0', '%005b00');
+assert.sameValue(unescape('%0%u005B0'), '%0[0', '%005B00');
+
+assert.sameValue(unescape('%0%u005e0'), '%0^0', '%005e00');
+assert.sameValue(unescape('%0%u005E0'), '%0^0', '%005E00');
+assert.sameValue(unescape('%0%u005f0'), '%0_0', '%005f00');
+assert.sameValue(unescape('%0%u005F0'), '%0_0', '%005F00');
+assert.sameValue(unescape('%0%u00600'), '%0`0', '%006000');
+assert.sameValue(unescape('%0%u00610'), '%0a0', '%006100');
+
+assert.sameValue(unescape('%0%u007a0'), '%0z0', '%007a00');
+assert.sameValue(unescape('%0%u007A0'), '%0z0', '%007A00');
+assert.sameValue(unescape('%0%u007b0'), '%0{0', '%007b00');
+assert.sameValue(unescape('%0%u007B0'), '%0{0', '%007B00');
+
+assert.sameValue(unescape('%0%ufffe0'), '%0\ufffe0', '%ufffe');
+assert.sameValue(unescape('%0%uFffe0'), '%0\ufffe0', '%uFffe');
+assert.sameValue(unescape('%0%ufFfe0'), '%0\ufffe0', '%ufFfe');
+assert.sameValue(unescape('%0%uffFe0'), '%0\ufffe0', '%uffFe');
+assert.sameValue(unescape('%0%ufffE0'), '%0\ufffe0', '%ufffE');
+assert.sameValue(unescape('%0%uFFFE0'), '%0\ufffe0', '%uFFFE');
+
+assert.sameValue(unescape('%0%uffff0'), '%0\uffff0', '%uffff');
+assert.sameValue(unescape('%0%uFfff0'), '%0\uffff0', '%uFfff');
+assert.sameValue(unescape('%0%ufFff0'), '%0\uffff0', '%ufFff');
+assert.sameValue(unescape('%0%uffFf0'), '%0\uffff0', '%uffFf');
+assert.sameValue(unescape('%0%ufffF0'), '%0\uffff0', '%ufffF');
+assert.sameValue(unescape('%0%uFFFF0'), '%0\uffff0', '%uFFFF');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/length.js b/js/src/tests/test262/annexB/built-ins/unescape/length.js
new file mode 100644
index 0000000000..2bd578f6ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.1.2
+description: >
+ unescape.length is 1.
+info: |
+ unescape (string)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(unescape, "length", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: 1
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/name.js b/js/src/tests/test262/annexB/built-ins/unescape/name.js
new file mode 100644
index 0000000000..e356381754
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: B.2.1.2
+description: >
+ unescape.name is "unescape".
+info: |
+ unescape (string)
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(unescape, "name", {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: "unescape"
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/not-a-constructor.js b/js/src/tests/test262/annexB/built-ins/unescape/not-a-constructor.js
new file mode 100644
index 0000000000..71c32f22c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/not-a-constructor.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ unescape does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(unescape), false, 'isConstructor(unescape) must return false');
+
+assert.throws(TypeError, () => {
+ new unescape('');
+}, '`new unescape(\'\')` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/prop-desc.js b/js/src/tests/test262/annexB/built-ins/unescape/prop-desc.js
new file mode 100644
index 0000000000..67a88bc87a
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: B.2.2
+description: >
+ Object.getOwnPropertyDescriptor returns data desc for functions on
+ built-ins (Global.unescape)
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof this.unescape, "function");
+assert.sameValue(typeof this["unescape"], "function");
+
+verifyProperty(this, "unescape", {
+ writable: true,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/shell.js b/js/src/tests/test262/annexB/built-ins/unescape/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-err.js b/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-err.js
new file mode 100644
index 0000000000..57b1f1d621
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+description: If [Symbol.toPrimitive] method returned an object, it should throw a TypeError
+info: |
+ B.2.1.2 unescape ( string )
+
+ 1. Set string to ? ToString(string).
+ ....
+features: [Symbol.toPrimitive]
+---*/
+
+var obj = {
+ toString() { throw new Test262Error('this should be unreachable'); },
+ valueOf() { throw new Test262Error('this should be unreachable'); },
+ [Symbol.toPrimitive]() { return function(){}; }
+};
+
+assert.throws(TypeError, function() {
+ unescape(obj);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-observe.js b/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-observe.js
new file mode 100644
index 0000000000..3c6c2068e1
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/to-primitive-observe.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2020 Qu Xing. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+description: Observable operations from string coercion
+info: |
+ B.2.1.2 unescape ( string )
+
+ 1. Set string to ? ToString(string).
+ ....
+features: [Symbol.toPrimitive]
+---*/
+
+var obj = {
+ toString() { throw new Test262Error('this should be unreachable'); },
+ valueOf() { throw new Test262Error('this should be unreachable'); },
+ [Symbol.toPrimitive]() { return 'success'; }
+};
+
+assert.sameValue(unescape(obj), 'success');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/to-string-err-symbol.js b/js/src/tests/test262/annexB/built-ins/unescape/to-string-err-symbol.js
new file mode 100644
index 0000000000..b09654e049
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/to-string-err-symbol.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Abrupt completion from `ToString` operation (Symbol value)
+info: |
+ 1. Let string be ? ToString(string).
+features: [Symbol]
+---*/
+
+var s = Symbol('');
+
+assert.throws(TypeError, function() {
+ unescape(s);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/to-string-err.js b/js/src/tests/test262/annexB/built-ins/unescape/to-string-err.js
new file mode 100644
index 0000000000..6bb51700c9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/to-string-err.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Abrupt completion from `ToString` operation
+info: |
+ 1. Let string be ? ToString(string).
+---*/
+
+var obj = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ unescape(obj);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/to-string-observe.js b/js/src/tests/test262/annexB/built-ins/unescape/to-string-observe.js
new file mode 100644
index 0000000000..bfba45da2d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/to-string-observe.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Observable operations from string coercion
+info: |
+ 1. Let string be ? ToString(string).
+---*/
+
+var log, obj;
+
+log = '';
+obj = {
+ toString: function() {
+ log += 'toString';
+ },
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+unescape(obj);
+
+assert.sameValue(log, 'toString');
+
+log = '';
+obj = {
+ toString: null,
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+unescape(obj);
+
+assert.sameValue(log, 'valueOf');
+
+log = '';
+obj = {
+ toString: function() {
+ log += 'toString';
+ return {};
+ },
+ valueOf: function() {
+ log += 'valueOf';
+ }
+};
+
+unescape(obj);
+
+assert.sameValue(log, 'toStringvalueOf');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-end-str.js b/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-end-str.js
new file mode 100644
index 0000000000..faabd5a50d
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-end-str.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: >
+ Does not transform two-character patterns that are interrupted by the end
+ of the string
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ [...]
+ ii. Else if k ≤ length-3 and the two code units at indices k+1 and
+ k+2 within string are both hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by two zeroes plus the two hexadecimal digits at indices k+1
+ and k+2 within string.
+ 2. Increase k by 2.
+ [...]
+---*/
+
+assert.sameValue(unescape('%'), '%');
+assert.sameValue(unescape('%0'), '%0');
+assert.sameValue(unescape('%1'), '%1');
+assert.sameValue(unescape('%2'), '%2');
+assert.sameValue(unescape('%3'), '%3');
+assert.sameValue(unescape('%4'), '%4');
+assert.sameValue(unescape('%5'), '%5');
+assert.sameValue(unescape('%6'), '%6');
+assert.sameValue(unescape('%7'), '%7');
+assert.sameValue(unescape('%8'), '%8');
+assert.sameValue(unescape('%9'), '%9');
+assert.sameValue(unescape('%a'), '%a');
+assert.sameValue(unescape('%A'), '%A');
+assert.sameValue(unescape('%b'), '%b');
+assert.sameValue(unescape('%B'), '%B');
+assert.sameValue(unescape('%c'), '%c');
+assert.sameValue(unescape('%C'), '%C');
+assert.sameValue(unescape('%d'), '%d');
+assert.sameValue(unescape('%D'), '%D');
+assert.sameValue(unescape('%e'), '%e');
+assert.sameValue(unescape('%E'), '%E');
+assert.sameValue(unescape('%f'), '%f');
+assert.sameValue(unescape('%F'), '%F');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-non-hex.js b/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-non-hex.js
new file mode 100644
index 0000000000..04d8948211
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/two-ignore-non-hex.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: >
+ Does not transform two-character patterns that contain non-hexadecimal
+ digits
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ [...]
+ ii. Else if k ≤ length-3 and the two code units at indices k+1 and
+ k+2 within string are both hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by two zeroes plus the two hexadecimal digits at indices k+1
+ and k+2 within string.
+ 2. Increase k by 2.
+ [...]
+---*/
+
+assert.sameValue(unescape('%0%0'), '%0%0');
+
+assert.sameValue(unescape('%0g0'), '%0g0');
+assert.sameValue(unescape('%0G0'), '%0G0');
+assert.sameValue(unescape('%g00'), '%g00');
+assert.sameValue(unescape('%G00'), '%G00');
+
+assert.sameValue(unescape('%0u0'), '%0u0');
+assert.sameValue(unescape('%0U0'), '%0U0');
+assert.sameValue(unescape('%u00'), '%u00');
+assert.sameValue(unescape('%U00'), '%U00');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/built-ins/unescape/two.js b/js/src/tests/test262/annexB/built-ins/unescape/two.js
new file mode 100644
index 0000000000..5f28cdd0c9
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/unescape/two.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-unescape-string
+es6id: B.2.1.2
+description: Translation of patterns with two digits
+info: |
+ [...]
+ 5. Repeat, while k ≠ length,
+ [...]
+ a. Let c be the code unit at index k within string.
+ b. If c is %, then
+ [...]
+ ii. Else if k ≤ length-3 and the two code units at indices k+1 and
+ k+2 within string are both hexadecimal digits, then
+ 1. Let c be the code unit whose value is the integer represented
+ by two zeroes plus the two hexadecimal digits at indices k+1
+ and k+2 within string.
+ 2. Increase k by 2.
+ [...]
+---*/
+
+assert.sameValue(unescape('%0%0000'), '%0\x0000', '%00');
+assert.sameValue(unescape('%0%0100'), '%0\x0100', '%01');
+
+assert.sameValue(unescape('%0%2900'), '%0)00', '%29');
+assert.sameValue(unescape('%0%2a00'), '%0*00', '%2a');
+assert.sameValue(unescape('%0%2A00'), '%0*00', '%2A');
+assert.sameValue(unescape('%0%2b00'), '%0+00', '%2b');
+assert.sameValue(unescape('%0%2B00'), '%0+00', '%2B');
+assert.sameValue(unescape('%0%2c00'), '%0,00', '%2c');
+assert.sameValue(unescape('%0%2C00'), '%0,00', '%2C');
+assert.sameValue(unescape('%0%2d00'), '%0-00', '%2d');
+assert.sameValue(unescape('%0%2D00'), '%0-00', '%2D');
+
+assert.sameValue(unescape('%0%3900'), '%0900', '%39');
+assert.sameValue(unescape('%0%3a00'), '%0:00', '%3A');
+assert.sameValue(unescape('%0%3A00'), '%0:00', '%3A');
+
+assert.sameValue(unescape('%0%3f00'), '%0?00', '%3f');
+assert.sameValue(unescape('%0%3F00'), '%0?00', '%3F');
+assert.sameValue(unescape('%0%4000'), '%0@00', '%40');
+
+assert.sameValue(unescape('%0%5a00'), '%0Z00', '%5a');
+assert.sameValue(unescape('%0%5A00'), '%0Z00', '%5A');
+assert.sameValue(unescape('%0%5b00'), '%0[00', '%5b');
+assert.sameValue(unescape('%0%5B00'), '%0[00', '%5B');
+
+assert.sameValue(unescape('%0%5e00'), '%0^00', '%5e');
+assert.sameValue(unescape('%0%5E00'), '%0^00', '%5E');
+assert.sameValue(unescape('%0%5f00'), '%0_00', '%5f');
+assert.sameValue(unescape('%0%5F00'), '%0_00', '%5F');
+assert.sameValue(unescape('%0%6000'), '%0`00', '%60');
+assert.sameValue(unescape('%0%6100'), '%0a00', '%61');
+
+assert.sameValue(unescape('%0%7a00'), '%0z00', '%7a');
+assert.sameValue(unescape('%0%7A00'), '%0z00', '%7A');
+assert.sameValue(unescape('%0%7b00'), '%0{00', '%7b');
+assert.sameValue(unescape('%0%7B00'), '%0{00', '%7B');
+
+assert.sameValue(unescape('%0%fe00'), '%0\xfe00', '%fe');
+assert.sameValue(unescape('%0%Fe00'), '%0\xfe00', '%Fe');
+assert.sameValue(unescape('%0%fE00'), '%0\xfe00', '%fE');
+assert.sameValue(unescape('%0%FE00'), '%0\xfe00', '%FE');
+
+assert.sameValue(unescape('%0%ff00'), '%0\xff00', '%ff');
+assert.sameValue(unescape('%0%Ff00'), '%0\xff00', '%Ff');
+assert.sameValue(unescape('%0%fF00'), '%0\xff00', '%fF');
+assert.sameValue(unescape('%0%FF00'), '%0\xff00', '%FF');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/browser.js b/js/src/tests/test262/annexB/language/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/browser.js
diff --git a/js/src/tests/test262/annexB/language/comments/browser.js b/js/src/tests/test262/annexB/language/comments/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/browser.js
diff --git a/js/src/tests/test262/annexB/language/comments/multi-line-html-close.js b/js/src/tests/test262/annexB/language/comments/multi-line-html-close.js
new file mode 100644
index 0000000000..5f5046bfe7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/multi-line-html-close.js
@@ -0,0 +1,90 @@
+// |reftest| error:Test262Error
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-html-like-comments
+description: Optional HTMLCloseComment following MultiLineComment
+info: |
+ Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+ MultiLineComment ::
+ /* FirstCommentLine[opt] LineTerminator MultiLineCommentChars[opt] * / HTMLCloseComment[opt]
+
+ HTMLCloseComment ::
+ WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]
+negative:
+ phase: runtime
+ type: Test262Error
+---*/
+
+var counter = 0;
+/*
+*/-->
+counter += 1;
+
+/*
+*/-->the comment extends to these characters
+counter += 1;
+
+/* optional FirstCommentLine
+*/-->the comment extends to these characters
+counter += 1;
+
+/*
+optional
+MultiLineCommentChars */-->the comment extends to these characters
+counter += 1;
+
+/*
+*/ /* optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+/*
+*/ /**/ /* second optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+// The V8 engine exhibited a bug where HTMLCloseComment was not recognized
+// within MultiLineComment in cases where MultiLineComment was not the first
+// token on the line of source text. The following tests demonstrate the same
+// productions listed above with the addition of such a leading token.
+
+0/*
+*/-->
+counter += 1;
+
+0/*
+*/-->the comment extends to these characters
+counter += 1;
+
+0/* optional FirstCommentLine
+*/-->the comment extends to these characters
+counter += 1;
+
+0/*
+optional
+MultiLineCommentChars */-->the comment extends to these characters
+counter += 1;
+
+0/*
+*/ /* optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+0/*
+*/ /**/ /* second optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+// Because this test concerns the interpretation of non-executable character
+// sequences within ECMAScript source code, special care must be taken to
+// ensure that executable code is evaluated as expected.
+//
+// Express the intended behavior by intentionally throwing an error; this
+// guarantees that test runners will only consider the test "passing" if
+// executable sequences are correctly interpreted as such.
+if (counter === 12) {
+ throw new Test262Error();
+}
diff --git a/js/src/tests/test262/annexB/language/comments/shell.js b/js/src/tests/test262/annexB/language/comments/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/shell.js
diff --git a/js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js b/js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js
new file mode 100644
index 0000000000..843527d464
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js
@@ -0,0 +1,39 @@
+// |reftest| error:Test262Error
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-html-like-comments
+description: >
+ A SingleLineHTMLCloseComment is considered to be a LineTerminator for
+ purposes of parsing by the syntactic grammar.
+info: |
+ Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+ MultiLineComment ::
+ /* FirstCommentLine[opt] LineTerminator MultiLineCommentChars[opt] * / HTMLCloseComment[opt]
+
+ HTMLCloseComment ::
+ WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]
+negative:
+ phase: runtime
+ type: Test262Error
+---*/
+
+var foo = [23]
+-->[0];
+
+// Because this test concerns the interpretation of non-executable character
+// sequences within ECMAScript source code, special care must be taken to
+// ensure that executable code is evaluated as expected.
+//
+// Express the intended behavior by intentionally throwing an error; this
+// guarantees that test runners will only consider the test "passing" if
+// executable sequences are correctly interpreted as such.
+if (foo[0] === 23) {
+ throw new Test262Error();
+}
diff --git a/js/src/tests/test262/annexB/language/comments/single-line-html-close-unicode-separators.js b/js/src/tests/test262/annexB/language/comments/single-line-html-close-unicode-separators.js
new file mode 100644
index 0000000000..8136a5db25
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-close-unicode-separators.js
@@ -0,0 +1,52 @@
+// |reftest| error:Test262Error
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-html-like-comments
+description: SingleLineHTMLCloseComment
+info: |
+ Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+ SingleLineHTMLCloseComment ::
+ LineTerminatorSequenceHTMLCloseComment
+
+ HTMLCloseComment ::
+ WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]
+negative:
+ phase: runtime
+ type: Test262Error
+---*/
+
+var counter = 0;
+
+// DANGER WILL ROBINSON!
+//
+// There are UTF-8-encoded Unicode separators in the lines below. Some text
+// editors (notably including, in the experience of this test's author, the
+// GNOME Text Editor used to attempt to create this file) don't properly insert
+// and save both these characters. (It seemed to handle copy/pasting U+2028
+// LINE SEPARATOR from GNOME Character Map just fine, but U+2029 PARAGRAPH
+// SEPARATOR got mangled in the final saved file.) Be extremely careful editing
+// this file to not inadvertently break this test.
+
+counter
-->a U+2028 LINE SEPARATOR between "counter" and "-->" means this is all a comment
+counter += 1;
+
+counter
-->a U+2029 PARAGRAPH SEPARATOR between "counter" and "-->" means this is all a comment
+counter += 1;
+
+// Because this test concerns the interpretation of non-executable character
+// sequences within ECMAScript source code, special care must be taken to
+// ensure that executable code is evaluated as expected.
+//
+// Express the intended behavior by intentionally throwing an error; this
+// guarantees that test runners will only consider the test "passing" if
+// executable sequences are correctly interpreted as such.
+if (counter === 2) {
+ throw new Test262Error();
+}
diff --git a/js/src/tests/test262/annexB/language/comments/single-line-html-close.js b/js/src/tests/test262/annexB/language/comments/single-line-html-close.js
new file mode 100644
index 0000000000..27d8bc2a05
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-close.js
@@ -0,0 +1,50 @@
+// |reftest| error:Test262Error
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-html-like-comments
+description: SingleLineHTMLCloseComment
+info: |
+ Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+ SingleLineHTMLCloseComment ::
+ LineTerminatorSequenceHTMLCloseComment
+
+ HTMLCloseComment ::
+ WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]
+negative:
+ phase: runtime
+ type: Test262Error
+---*/
+
+var counter = 0;
+-->
+counter += 1;
+
+-->the comment extends to these characters
+counter += 1;
+
+ -->the comment extends to these characters
+counter += 1;
+
+/* optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+/**/ /* second optional SingleLineDelimitedCommentSequence */-->the comment extends to these characters
+counter += 1;
+
+// Because this test concerns the interpretation of non-executable character
+// sequences within ECMAScript source code, special care must be taken to
+// ensure that executable code is evaluated as expected.
+//
+// Express the intended behavior by intentionally throwing an error; this
+// guarantees that test runners will only consider the test "passing" if
+// executable sequences are correctly interpreted as such.
+if (counter === 5) {
+ throw new Test262Error();
+}
diff --git a/js/src/tests/test262/annexB/language/comments/single-line-html-open.js b/js/src/tests/test262/annexB/language/comments/single-line-html-open.js
new file mode 100644
index 0000000000..c9dd1791ad
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-open.js
@@ -0,0 +1,44 @@
+// |reftest| error:Test262Error
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-html-like-comments
+description: SingleLineHTMLOpenComment
+info: |
+ Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+ SingleLineHTMLOpenComment ::
+ <!--SingleLineCommentCharsopt
+negative:
+ phase: runtime
+ type: Test262Error
+---*/
+
+var counter = 0;
+<!--
+counter += 1;
+
+<!--the comment extends to these characters
+counter += 1;
+
+counter += 1;<!--the comment extends to these characters
+counter += 1;
+
+var x = 0;
+x = -1 <!--x;
+
+// Because this test concerns the interpretation of non-executable character
+// sequences within ECMAScript source code, special care must be taken to
+// ensure that executable code is evaluated as expected.
+//
+// Express the intended behavior by intentionally throwing an error; this
+// guarantees that test runners will only consider the test "passing" if
+// executable sequences are correctly interpreted as such.
+if (counter === 4 && x === -1) {
+ throw new Test262Error();
+}
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/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
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/browser.js b/js/src/tests/test262/annexB/language/expressions/assignment/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/dstr/array-pattern-emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/array-pattern-emulates-undefined.js
new file mode 100644
index 0000000000..e65bbe0aae
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/array-pattern-emulates-undefined.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-destructuring-binding-patterns-runtime-semantics-bindinginitialization
+description: >
+ Destructuring initializer is not evaluated when value is an object
+ with [[IsHTMLDDA]] internal slot.
+info: |
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+ 2. Let result be IteratorBindingInitialization of ArrayBindingPattern with arguments
+ iteratorRecord and environment.
+ 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
+ 4. Return result.
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer[opt]
+
+ [...]
+ 5. If Initializer is present and v is undefined, then
+ [...]
+ 6. If environment is undefined, return ? PutValue(lhs, v).
+features: [destructuring-binding, IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var initCount = 0;
+var counter = function() {
+ initCount += 1;
+};
+
+var x;
+([x = counter()] = [IsHTMLDDA]);
+
+assert.sameValue(x, IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+var base = {};
+([base.y = counter()] = [IsHTMLDDA]);
+
+assert.sameValue(base.y, IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/dstr/browser.js b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/dstr/object-pattern-emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/object-pattern-emulates-undefined.js
new file mode 100644
index 0000000000..d9fe3d1bc3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/object-pattern-emulates-undefined.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-destructuring-binding-patterns-runtime-semantics-bindinginitialization
+description: >
+ Destructuring initializer is not evaluated when value is an object
+ with [[IsHTMLDDA]] internal slot.
+info: |
+ BindingPattern : ObjectBindingPattern
+
+ 1. Perform ? RequireObjectCoercible(value).
+ 2. Return the result of performing BindingInitialization for
+ ObjectBindingPattern using value and environment as arguments.
+
+ Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer[opt]
+
+ [...]
+ 4. If Initializer is present and v is undefined, then
+ [...]
+ 5. If environment is undefined, return ? PutValue(lhs, v).
+features: [destructuring-binding, IsHTMLDDA]
+---*/
+
+var initCount = 0;
+var counter = function() {
+ initCount += 1;
+};
+
+var x, IsHTMLDDA = $262.IsHTMLDDA;
+({x = counter()} = {x: IsHTMLDDA});
+
+assert.sameValue(x, IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/dstr/shell.js b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/dstr/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/assignment/shell.js b/js/src/tests/test262/annexB/language/expressions/assignment/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/assignment/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/browser.js b/js/src/tests/test262/annexB/language/expressions/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/coalesce/browser.js b/js/src/tests/test262/annexB/language/expressions/coalesce/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/coalesce/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/coalesce/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/coalesce/emulates-undefined.js
new file mode 100644
index 0000000000..25b883759d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/coalesce/emulates-undefined.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: >
+ ?? doesn't special-case [[IsHTMLDDA]] object; rval is not evaluated.
+info: |
+ CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
+
+ 1. Let lref be the result of evaluating CoalesceExpressionHead.
+ 2. Let lval be ? GetValue(lref).
+ 3. If lval is undefined or null, then
+ [...]
+ 4. Otherwise, return lval.
+features: [IsHTMLDDA, coalesce-expression]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(IsHTMLDDA ?? unresolved, IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/coalesce/shell.js b/js/src/tests/test262/annexB/language/expressions/coalesce/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/coalesce/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/conditional/browser.js b/js/src/tests/test262/annexB/language/expressions/conditional/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/conditional/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/conditional/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/conditional/emulates-undefined.js
new file mode 100644
index 0000000000..733d6b239b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/conditional/emulates-undefined.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-conditional-operator-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; trueRef is not evaluated.
+info: |
+ ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
+
+ 1. Let lref be the result of evaluating ShortCircuitExpression.
+ 2. Let lval be ! ToBoolean(? GetValue(lref)).
+ 3. If lval is true, then
+ [...]
+ 4. Else,
+ a. Let falseRef be the result of evaluating the second AssignmentExpression.
+ b. Return ? GetValue(falseRef).
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA]
+---*/
+
+assert.sameValue($262.IsHTMLDDA ? unresolved : 2, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/conditional/shell.js b/js/src/tests/test262/annexB/language/expressions/conditional/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/conditional/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/does-not-equals/browser.js b/js/src/tests/test262/annexB/language/expressions/does-not-equals/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/does-not-equals/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/does-not-equals/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/does-not-equals/emulates-undefined.js
new file mode 100644
index 0000000000..15928d2065
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/does-not-equals/emulates-undefined.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-equality-operators-runtime-semantics-evaluation
+description: >
+ Abstract Equality special-cases [[IsHTMLDDA]] objects with `undefined` and `null`.
+info: |
+ EqualityExpression : EqualityExpression != RelationalExpression
+
+ [...]
+ 5. Let r be the result of performing Abstract Equality Comparison rval == lval.
+ 6. ReturnIfAbrupt(r).
+ 7. If r is true, return false. Otherwise, return true.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to Abstract Equality Comparison
+
+ The following steps are inserted after step 3 of the Abstract Equality Comparison algorithm:
+
+ 1. If Type(x) is Object and x has an [[IsHTMLDDA]] internal slot and y is either null or undefined, return true.
+ 2. If x is either null or undefined and Type(y) is Object and y has an [[IsHTMLDDA]] internal slot, return true.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(IsHTMLDDA != undefined, false, "!= with `undefined`");
+assert.sameValue(undefined != IsHTMLDDA, false, "!= with `undefined`");
+
+assert.sameValue(IsHTMLDDA != null, false, "!= with `null`");
+assert.sameValue(null != IsHTMLDDA, false, "!= with `null`");
+
+assert.sameValue(IsHTMLDDA != IsHTMLDDA, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/does-not-equals/shell.js b/js/src/tests/test262/annexB/language/expressions/does-not-equals/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/does-not-equals/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/equals/browser.js b/js/src/tests/test262/annexB/language/expressions/equals/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/equals/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/equals/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/equals/emulates-undefined.js
new file mode 100644
index 0000000000..ca0a8805f1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/equals/emulates-undefined.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-equality-operators-runtime-semantics-evaluation
+description: >
+ Abstract Equality special-cases [[IsHTMLDDA]] objects with `undefined` and `null`.
+info: |
+ EqualityExpression : EqualityExpression == RelationalExpression
+
+ [...]
+ 5. Return the result of performing Abstract Equality Comparison rval == lval.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to Abstract Equality Comparison
+
+ The following steps are inserted after step 3 of the Abstract Equality Comparison algorithm:
+
+ 1. If Type(x) is Object and x has an [[IsHTMLDDA]] internal slot and y is either null or undefined, return true.
+ 2. If x is either null or undefined and Type(y) is Object and y has an [[IsHTMLDDA]] internal slot, return true.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert(IsHTMLDDA == undefined, "== with `undefined`");
+assert(undefined == IsHTMLDDA, "== with `undefined`");
+
+assert(IsHTMLDDA == null, "== with `null`");
+assert(null == IsHTMLDDA, "== with `null`");
+
+assert(IsHTMLDDA == IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/equals/shell.js b/js/src/tests/test262/annexB/language/expressions/equals/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/equals/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-and/browser.js b/js/src/tests/test262/annexB/language/expressions/logical-and/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-and/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-and/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/logical-and/emulates-undefined.js
new file mode 100644
index 0000000000..ddfaa3c5fa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-and/emulates-undefined.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-logical-operators-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; rval is not evaluated.
+info: |
+ LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
+
+ 1. Let lref be the result of evaluating LogicalANDExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is false, return lval.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(IsHTMLDDA && unresolved, IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-and/shell.js b/js/src/tests/test262/annexB/language/expressions/logical-and/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-and/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-assignment/browser.js b/js/src/tests/test262/annexB/language/expressions/logical-assignment/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-assignment/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-and.js b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-and.js
new file mode 100644
index 0000000000..51587a812e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-and.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; rval is not evaluated.
+info: |
+ AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is false, return lval.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA, logical-assignment-operators]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var value = IsHTMLDDA;
+assert.sameValue(value &&= unresolved, IsHTMLDDA);
+assert.sameValue(value, IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-coalesce.js b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-coalesce.js
new file mode 100644
index 0000000000..621b6ee8da
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-coalesce.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ??= doesn't special-case [[IsHTMLDDA]] object; rval is not evaluated.
+info: |
+ AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. If lval is neither undefined nor null, return lval.
+features: [IsHTMLDDA, logical-assignment-operators]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var value = IsHTMLDDA;
+assert.sameValue(value ??= unresolved, IsHTMLDDA);
+assert.sameValue(value, IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-or.js b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-or.js
new file mode 100644
index 0000000000..a79beda74d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-assignment/emulates-undefined-or.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-assignment-operators-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; rval is evaluated.
+info: |
+ AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
+
+ 1. Let lref be the result of evaluating LeftHandSideExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ [...]
+ 7. Perform ? PutValue(lref, rval).
+ 8. Return rval.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA, logical-assignment-operators]
+---*/
+
+var value = $262.IsHTMLDDA;
+assert.sameValue(value ||= 2, 2);
+assert.sameValue(value, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-assignment/shell.js b/js/src/tests/test262/annexB/language/expressions/logical-assignment/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-assignment/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-not/browser.js b/js/src/tests/test262/annexB/language/expressions/logical-not/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-not/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-not/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/logical-not/emulates-undefined.js
new file mode 100644
index 0000000000..b559b94730
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-not/emulates-undefined.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-logical-operators-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object.
+info: |
+ UnaryExpression : ! UnaryExpression
+
+ 1. Let expr be the result of evaluating UnaryExpression.
+ 2. Let oldValue be ! ToBoolean(? GetValue(expr)).
+ 3. If oldValue is true, return false.
+ 4. Return true.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert(!IsHTMLDDA);
+assert.sameValue(!!IsHTMLDDA, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-not/shell.js b/js/src/tests/test262/annexB/language/expressions/logical-not/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-not/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-or/browser.js b/js/src/tests/test262/annexB/language/expressions/logical-or/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-or/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-or/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/logical-or/emulates-undefined.js
new file mode 100644
index 0000000000..13049c5c55
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-or/emulates-undefined.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-logical-operators-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; rval is evaluated.
+info: |
+ LogicalORExpression : LogicalORExpression || LogicalANDExpression
+
+ 1. Let lref be the result of evaluating LogicalORExpression.
+ 2. Let lval be ? GetValue(lref).
+ 3. Let lbool be ! ToBoolean(lval).
+ 4. If lbool is true, return lval.
+ 5. Let rref be the result of evaluating LogicalANDExpression.
+ 6. Return ? GetValue(rref).
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA]
+---*/
+
+assert.sameValue($262.IsHTMLDDA || 2, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/logical-or/shell.js b/js/src/tests/test262/annexB/language/expressions/logical-or/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/logical-or/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/shell.js b/js/src/tests/test262/annexB/language/expressions/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/browser.js b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/emulates-undefined.js
new file mode 100644
index 0000000000..7717308664
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-equality-operators-runtime-semantics-evaluation
+description: >
+ Strict Equality Comparison doesn't special-case [[IsHTMLDDA]] objects.
+info: |
+ EqualityExpression : EqualityExpression !== RelationalExpression
+
+ [...]
+ 5. Let r be the result of performing Strict Equality Comparison rval === lval.
+ 6. Assert: r is a normal completion.
+ 7. If r.[[Value]] is true, return false. Otherwise, return true.
+
+ Strict Equality Comparison
+
+ 1. If Type(x) is different from Type(y), return false.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert(IsHTMLDDA !== undefined, "!== with `undefined`");
+assert(undefined !== IsHTMLDDA, "!== with `undefined`");
+
+assert(IsHTMLDDA !== null, "!== with `null`");
+assert(null !== IsHTMLDDA, "!== with `null`");
+
+assert.sameValue(IsHTMLDDA !== IsHTMLDDA, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/shell.js b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-does-not-equals/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-equals/browser.js b/js/src/tests/test262/annexB/language/expressions/strict-equals/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-equals/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-equals/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/strict-equals/emulates-undefined.js
new file mode 100644
index 0000000000..67c6603cdd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-equals/emulates-undefined.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-equality-operators-runtime-semantics-evaluation
+description: >
+ Strict Equality Comparison doesn't special-case [[IsHTMLDDA]] objects.
+info: |
+ EqualityExpression : EqualityExpression === RelationalExpression
+
+ [...]
+ 5. Return the result of performing Strict Equality Comparison rval === lval.
+
+ Strict Equality Comparison
+
+ 1. If Type(x) is different from Type(y), return false.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(IsHTMLDDA === undefined, false, "=== with `undefined`");
+assert.sameValue(undefined === IsHTMLDDA, false, "=== with `undefined`");
+
+assert.sameValue(IsHTMLDDA === null, false, "=== with `null`");
+assert.sameValue(null === IsHTMLDDA, false, "=== with `null`");
+
+assert(IsHTMLDDA === IsHTMLDDA);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/strict-equals/shell.js b/js/src/tests/test262/annexB/language/expressions/strict-equals/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/strict-equals/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/template-literal/browser.js b/js/src/tests/test262/annexB/language/expressions/template-literal/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/template-literal/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-non-strict.js b/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-non-strict.js
new file mode 100644
index 0000000000..20ecbcc80b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-non-strict.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 12.2.8
+description: >
+ The expression within the template should be evaluated according to the
+ semantics of the surrounding context.
+ The SV of EscapeSequence :: HexEscapeSequence is the SV of the
+ HexEscapeSequence.
+flags: [noStrict]
+---*/
+
+assert.sameValue(`${'\07'}`, '\u0007');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict-strict.js b/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict-strict.js
new file mode 100644
index 0000000000..19a2f03bd4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict-strict.js
@@ -0,0 +1,20 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 12.2.8
+description: >
+ The expression within the template should be evaluated according to the
+ semantics of the surrounding context.
+ The SV of EscapeSequence :: HexEscapeSequence is the SV of the
+ HexEscapeSequence.
+negative:
+ phase: parse
+ type: SyntaxError
+flags: [onlyStrict]
+---*/
+
+$DONOTEVALUATE();
+
+`${'\07'}`;
diff --git a/js/src/tests/test262/annexB/language/expressions/template-literal/shell.js b/js/src/tests/test262/annexB/language/expressions/template-literal/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/template-literal/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/typeof/browser.js b/js/src/tests/test262/annexB/language/expressions/typeof/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/typeof/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/typeof/emulates-undefined.js b/js/src/tests/test262/annexB/language/expressions/typeof/emulates-undefined.js
new file mode 100644
index 0000000000..464a80f84c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/typeof/emulates-undefined.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-IsHTMLDDA-internal-slot-typeof
+description: >
+ `typeof` operator returns "undefined" for [[IsHTMLDDA]] object.
+info: |
+ Changes to the typeof Operator
+
+ The following table entry is inserted into Table 35 immediately
+ preceeding the entry for "Object (implements [[Call]])":
+
+ Type of val: Object (has an [[IsHTMLDDA]] internal slot)
+ Result: "undefined"
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert(typeof IsHTMLDDA === "undefined", '=== "undefined"');
+assert.sameValue(typeof IsHTMLDDA, "undefined");
+
+assert(typeof IsHTMLDDA !== "object", '!== "object"');
+assert.sameValue(typeof IsHTMLDDA === "object", false, '!== "object"');
+
+assert(typeof IsHTMLDDA !== "function", '!== "function"');
+assert.sameValue(typeof IsHTMLDDA === "function", false, '!== "function"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/typeof/shell.js b/js/src/tests/test262/annexB/language/expressions/typeof/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/typeof/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/yield/browser.js b/js/src/tests/test262/annexB/language/expressions/yield/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/yield/browser.js
diff --git a/js/src/tests/test262/annexB/language/expressions/yield/shell.js b/js/src/tests/test262/annexB/language/expressions/yield/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/yield/shell.js
diff --git a/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-return-emulates-undefined-throws-when-called.js b/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-return-emulates-undefined-throws-when-called.js
new file mode 100644
index 0000000000..c424651c61
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-return-emulates-undefined-throws-when-called.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: >
+ If <iterator>.return is an object emulating `undefined` (e.g. `document.all`
+ in browsers), it shouldn't be treated as if it were actually `undefined` by
+ the yield* operator.
+features: [generators, IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var iter = {
+ [Symbol.iterator]() { return this; },
+ next() { return {}; },
+ return: IsHTMLDDA,
+};
+
+var outer = (function*() { yield* iter; })();
+
+outer.next();
+
+assert.throws(TypeError, function() {
+ // `IsHTMLDDA` is called here with `iter` as `this` and `emptyString` as the
+ // sole argument, and it's specified to return `null` under these conditions.
+ // As `iter`'s iteration isn't ending because of a throw, the iteration
+ // protocol will then throw a `TypeError` because `null` isn't an object.
+ var emptyString = "";
+ outer.return(emptyString);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-throw-emulates-undefined-throws-when-called.js b/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-throw-emulates-undefined-throws-when-called.js
new file mode 100644
index 0000000000..bdeaa2051a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/expressions/yield/star-iterable-throw-emulates-undefined-throws-when-called.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: >
+ If <iterator>.throw is an object emulating `undefined` (e.g. `document.all`
+ in browsers), it shouldn't be treated as if it were actually `undefined` by
+ the yield* operator.
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ [...]
+ 7. Repeat,
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]] »).
+ [...]
+ 4. If Type(innerResult) is not Object, throw a TypeError exception.
+features: [generators, IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var returnCalls = 0;
+var inner = {
+ [Symbol.iterator]() { return this; },
+ next() { return {done: false}; },
+ throw: IsHTMLDDA,
+ return() {
+ returnCalls += 1;
+ return {done: true};
+ },
+};
+
+var outer = (function* () { yield* inner; })();
+outer.next();
+
+assert.throws(TypeError, function() {
+ // `IsHTMLDDA` is called here with `iter` as `this` and `emptyString` as the
+ // sole argument, and it's specified to return `null` under these conditions.
+ // As `iter`'s iteration isn't ending because of a throw, the iteration
+ // protocol will then throw a `TypeError` because `null` isn't an object.
+ var emptyString = "";
+ outer.throw(emptyString);
+});
+
+assert.sameValue(returnCalls, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js
new file mode 100644
index 0000000000..6700dcec8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-block-scoping.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: A block-scoped binding is created (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ {
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..19c91c981a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..4a090ca5a9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-block-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ {
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..154d6d0cd4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js
new file mode 100644
index 0000000000..27b1ea9276
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js
new file mode 100644
index 0000000000..50547ff772
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-no-init.js
@@ -0,0 +1,30 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js
new file mode 100644
index 0000000000..532e46b053
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-existing-var-update.js
@@ -0,0 +1,41 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js
new file mode 100644
index 0000000000..ce86d2797b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ {
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js
new file mode 100644
index 0000000000..e0cf6d2e54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-no-skip-try.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ {
+ function f() { return 123; }
+ }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js
new file mode 100644
index 0000000000..14772af5ff
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-arguments.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Functions named 'arguments' have legacy hoisting semantics
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [noStrict]
+info: |
+ FunctionDeclarationInstantiation ( _func_, _argumentsList_ )
+
+ [...]
+ 7. Let _parameterNames_ be the BoundNames of _formals_.
+ [...]
+ 22. If argumentsObjectNeeded is true, then
+ f. Append "arguments" to parameterNames.
+
+ Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the |FunctionDeclaration| _f_ with a |VariableStatement| that has _F_
+ as a |BindingIdentifier| would not produce any Early Errors for _func_ and _F_ is
+ not an element of _parameterNames_, then
+ [...]
+---*/
+
+// Simple parameters
+(function() {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+// Single named parameter
+(function(x) {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+// Non-simple parameters
+(function(..._) {
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+ {
+ assert.sameValue(arguments(), undefined);
+ function arguments() {}
+ assert.sameValue(arguments(), undefined);
+ }
+ assert.sameValue(arguments.toString(), "[object Arguments]");
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js
new file mode 100644
index 0000000000..b6518043ca
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-dft-param.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js
new file mode 100644
index 0000000000..f97a906e23
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-block.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ {
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..aed0866402
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-in.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ {
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..e715cb5204
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for-of.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ {
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js
new file mode 100644
index 0000000000..9a85550de4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-for.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ {
+ function f() { }
+ }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..cdd96eb131
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-switch.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ {
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js
new file mode 100644
index 0000000000..7acfcdcd79
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ {
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js
new file mode 100644
index 0000000000..28b12bc208
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js
new file mode 100644
index 0000000000..db5ac4fbab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-skip-param.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ {
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js b/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js
new file mode 100644
index 0000000000..9b621f3e09
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-func-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in function scope containing a function declaration)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ {
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js b/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
new file mode 100644
index 0000000000..c7e85de89a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2018 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ Nested function declarations, the second declaration is not Annex-B applicable.
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ a. For each FunctionDeclaration f that is directly contained in the
+ StatementList of a Block, CaseClause, or DefaultClause, do
+ i. Let F be StringValue of the BindingIdentifier of FunctionDeclaration f.
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of parameterNames, then
+ ...
+flags: [noStrict]
+---*/
+
+function g() {
+ // Create an outer block-statement.
+ {
+ // A lexically declared function declaration.
+ // This function is applicable for Annex-B semantics.
+ function f() { return 1; }
+
+ // An inner block-statement with another function declaration.
+ // This function is not applicable for Annex-B semantics, because
+ // replacing it with |var f| would result in a SyntaxError.
+ {
+ function f() { return 2; }
+ }
+ }
+
+ assert.sameValue(f(), 1);
+}
+
+g();
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js
new file mode 100644
index 0000000000..6c4a289682
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/block-decl-nostrict.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Block statement
+ in function code containing a function declaration
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ {
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/browser.js b/js/src/tests/test262/annexB/language/function-code/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/browser.js
diff --git a/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js
new file mode 100644
index 0000000000..1e3a163cd3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-block.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2019 Adrian Heine. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: In non-strict mode, duplicate LexicallyDeclaredNames in a block are allowed if they are bound by FunctionDeclarations
+esid: sec-block-duplicates-allowed-static-semantics
+es6id: B.3.3.4
+flags: [noStrict]
+info: |
+ B.3.3.4 Changes to Block Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ Block: {StatementList}
+
+ It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+---*/
+
+{ function a() {} function a() {} }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js
new file mode 100644
index 0000000000..2c03663358
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/function-redeclaration-switch.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 Adrian Heine. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: In non-strict mode, duplicate LexicallyDeclaredNames in a switch statement's CaseBlock are allowed if they are bound by FunctionDeclarations
+esid: sec-switch-duplicates-allowed-static-semantics
+es6id: B.3.3.5
+flags: [noStrict]
+info: |
+ B.3.3.4 Changes to Block Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ Block: {StatementList}
+
+ It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+
+
+ B.3.3.5 Changes to switch Statement Static Semantics: Early Errors
+
+ For web browser compatibility, that rule is modified with the addition of the **highlighted** text:
+
+ SwitchStatement: switch ( Expression ) CaseBlock
+
+ It is a Syntax Error if the LexicallyDeclaredNames of CaseBlock contains any duplicate entries, **unless the source code matching this production is not strict mode code and the duplicate entries are only bound by FunctionDeclarations**.
+---*/
+
+let x
+switch (x) {
+case 1:
+ function a() {}
+case 2:
+ function a() {}
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
new file mode 100644
index 0000000000..298013f304
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else function _f() {}
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..351f7cde4b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..9de2d7e5d5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; } else function _f() {}
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..5974dc3858
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js
new file mode 100644
index 0000000000..a15ad9f4f1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js
new file mode 100644
index 0000000000..53ad53abf9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js
new file mode 100644
index 0000000000..40541fdc07
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; } else function _f() {}
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js
new file mode 100644
index 0000000000..18f1176553
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { } else function _f() {}
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js
new file mode 100644
index 0000000000..7d22f11253
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ if (true) function f() { return 123; } else function _f() {}
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js
new file mode 100644
index 0000000000..8c3bc7ebb7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js
new file mode 100644
index 0000000000..b5b0aefa84
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ if (true) function f() { } else function _f() {}
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5772f7b450
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ if (true) function f() { } else function _f() {}
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..659b967860
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ if (true) function f() { } else function _f() {}
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js
new file mode 100644
index 0000000000..0b196cdbd6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ if (true) function f() { } else function _f() {}
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..8a1ac1fb56
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ if (true) function f() { } else function _f() {}
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js
new file mode 100644
index 0000000000..1c72b31349
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ if (true) function f() { } else function _f() {}
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js
new file mode 100644
index 0000000000..54639c774f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js
new file mode 100644
index 0000000000..10be89c4bf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { } else function _f() {}
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js
new file mode 100644
index 0000000000..2196f3670d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-a-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; } else function _f() {}
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js
new file mode 100644
index 0000000000..479cef98b6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..1dfd9399c1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..720594506b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (false) function _f() {} else function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..1f4137a1e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js
new file mode 100644
index 0000000000..5bd63bde74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js
new file mode 100644
index 0000000000..48a39bf46d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js
new file mode 100644
index 0000000000..6a33e16a67
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js
new file mode 100644
index 0000000000..d1b30c8891
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (false) function _f() {} else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js
new file mode 100644
index 0000000000..4e2237f997
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ if (false) function _f() {} else function f() { return 123; }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js
new file mode 100644
index 0000000000..9a9b036e02
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js
new file mode 100644
index 0000000000..27323b1de3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ if (false) function _f() {} else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..f9f4bf4e0c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ if (false) function _f() {} else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..de6f1953c0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ if (false) function _f() {} else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js
new file mode 100644
index 0000000000..7808944a3e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ if (false) function _f() {} else function f() { }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..b1c502a663
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ if (false) function _f() {} else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js
new file mode 100644
index 0000000000..2a72aeb9ba
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ if (false) function _f() {} else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js
new file mode 100644
index 0000000000..e3c1a40a12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js
new file mode 100644
index 0000000000..8d4f4e1ebf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (false) function _f() {} else function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js
new file mode 100644
index 0000000000..ddb511d8d4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-decl-b-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) function _f() {} else function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js
new file mode 100644
index 0000000000..1a0b2460a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else ;
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..b74fbff156
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..8d9a65d180
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; } else ;
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..b4d745aa51
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; } else ;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js
new file mode 100644
index 0000000000..f95dae5053
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; } else ;
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js
new file mode 100644
index 0000000000..61dedaada8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js
new file mode 100644
index 0000000000..296e77ea3c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; } else ;
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js
new file mode 100644
index 0000000000..21bb3ff317
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { } else ;
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js
new file mode 100644
index 0000000000..6e6d3d6f76
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ if (true) function f() { return 123; } else ;
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js
new file mode 100644
index 0000000000..c5b36b9656
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js
new file mode 100644
index 0000000000..c34431e6fc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ if (true) function f() { } else ;
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..58c7b94769
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ if (true) function f() { } else ;
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..ddc0028253
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ if (true) function f() { } else ;
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js
new file mode 100644
index 0000000000..e1c4f648de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ if (true) function f() { } else ;
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..cb73605211
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ if (true) function f() { } else ;
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js
new file mode 100644
index 0000000000..7de1c6c72f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ if (true) function f() { } else ;
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js
new file mode 100644
index 0000000000..0c86eea6a5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js
new file mode 100644
index 0000000000..ca71166ab5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { } else ;
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js
new file mode 100644
index 0000000000..5d784877be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-else-stmt-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; } else ;
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js
new file mode 100644
index 0000000000..9fb86796d4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..4c4f4d622d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..6b22f948b0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (true) function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..c0d9cb2d12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (true) function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js
new file mode 100644
index 0000000000..e90a392aa4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js
new file mode 100644
index 0000000000..9f7d817a74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js
new file mode 100644
index 0000000000..50f36bdcc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js
new file mode 100644
index 0000000000..1e83b641d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (true) function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js
new file mode 100644
index 0000000000..2b5b9b54f2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ if (true) function f() { return 123; }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js
new file mode 100644
index 0000000000..f69e1063be
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js
new file mode 100644
index 0000000000..050d97c218
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ if (true) function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..97fe839a55
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ if (true) function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4fb50227e5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ if (true) function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js
new file mode 100644
index 0000000000..1029f5f034
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ if (true) function f() { }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..1b0c0b8d78
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ if (true) function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js
new file mode 100644
index 0000000000..562e29900b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ if (true) function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js
new file mode 100644
index 0000000000..00459a239a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js
new file mode 100644
index 0000000000..00ba2976ac
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (true) function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js
new file mode 100644
index 0000000000..5038274c87
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-decl-no-else-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (true) function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js
new file mode 100644
index 0000000000..e8850b9c51
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-block-scoping.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..b3292466ed
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-no-init.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..ce84f7ed1c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-block-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ if (false) ; else function f() { return 'second declaration'; }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..5c649b8ccc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-no-init.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ if (false) ; else function f() { return 'inner declaration'; }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js
new file mode 100644
index 0000000000..2bdf2fadb7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-fn-update.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'inner declaration'; }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js
new file mode 100644
index 0000000000..0d9635df28
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-no-init.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js
new file mode 100644
index 0000000000..03f9416a2a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-existing-var-update.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'function declaration'; }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js
new file mode 100644
index 0000000000..3816385413
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-init.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ if (false) ; else function f() { }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js
new file mode 100644
index 0000000000..a574afb7f3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-no-skip-try.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ if (false) ; else function f() { return 123; }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js
new file mode 100644
index 0000000000..5e86815aec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-dft-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js
new file mode 100644
index 0000000000..fbce2691eb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-block.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ if (false) ; else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..85ecefb417
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-in.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ if (false) ; else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..1c6ef0d10b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for-of.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ if (false) ; else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js
new file mode 100644
index 0000000000..4e80a4479e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-for.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ if (false) ; else function f() { }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..9d97fa40f2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-switch.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ if (false) ; else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js
new file mode 100644
index 0000000000..ed0d06d49b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err-try.js
@@ -0,0 +1,65 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ if (false) ; else function f() { }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js
new file mode 100644
index 0000000000..4a8ac7ef54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-early-err.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js
new file mode 100644
index 0000000000..770713d5c1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-skip-param.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ if (false) ; else function f() { }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js
new file mode 100644
index 0000000000..05feeb50a3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/if-stmt-else-decl-func-update.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in function scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ if (false) ; else function f() { return 'declaration'; }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/shell.js b/js/src/tests/test262/annexB/language/function-code/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/shell.js
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js
new file mode 100644
index 0000000000..9a1d776960
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-decl-nostrict.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `case` clause of a `switch` statement in function code
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js
new file mode 100644
index 0000000000..5388791b85
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..15ef7e3fbc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-no-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..f667bf7507
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ switch (1) {
+ case 1:
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..04d8d3e0c6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js
new file mode 100644
index 0000000000..e76b044eb1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js
new file mode 100644
index 0000000000..603f17b7fc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js
new file mode 100644
index 0000000000..ec37b546af
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js
new file mode 100644
index 0000000000..9fa416ad1b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js
new file mode 100644
index 0000000000..4edbd0a847
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-no-skip-try.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ switch (1) {
+ case 1:
+ function f() { return 123; }
+ }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js
new file mode 100644
index 0000000000..f6ca9c65e2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-dft-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js
new file mode 100644
index 0000000000..5b8f50ed2f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-block.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..3aba8da1c9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-in.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..f949da87cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for-of.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js
new file mode 100644
index 0000000000..5ff85c5766
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-for.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..1ecf8cbbef
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-switch.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js
new file mode 100644
index 0000000000..eee62b5561
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err-try.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js
new file mode 100644
index 0000000000..87d64e1536
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-early-err.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js
new file mode 100644
index 0000000000..2d5699418b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-skip-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ switch (1) {
+ case 1:
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js b/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js
new file mode 100644
index 0000000000..cea6aa60a9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-case-func-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ case 1:
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js
new file mode 100644
index 0000000000..fbcfb8ca05
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-decl-nostrict.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-web-compat-functiondeclarationinstantiation
+description: >
+ AnnexB extension not honored in strict mode, Function declaration
+ in the `default` clause of a `switch` statement in function code
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ 1. If strict is false, then
+ ...
+
+flags: [noStrict]
+---*/
+
+var err1, err2;
+
+(function() {
+ try {
+ f;
+ } catch (exception) {
+ err1 = exception;
+ }
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ try {
+ f;
+ } catch (exception) {
+ err2 = exception;
+ }
+}());
+
+assert.sameValue(err1, undefined);
+assert.sameValue(err2, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js
new file mode 100644
index 0000000000..c18abba71b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-block-scoping.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV, varBinding;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+ }
+
+ varBinding = f;
+ f();
+}());
+
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ varBinding(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..57d48d90ef
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-no-init.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ {
+ function f() {}
+ }
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js
new file mode 100644
index 0000000000..83b4326ac3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-block-fn-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var updated;
+
+(function() {
+ {
+ function f() {
+ return 'first declaration';
+ }
+ }
+
+ switch (1) {
+ default:
+ function f() { return 'second declaration'; }
+ }
+
+ updated = f;
+}());
+
+assert.sameValue(typeof updated, 'function');
+assert.sameValue(updated(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js
new file mode 100644
index 0000000000..04afab4d5e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+ }
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(init(), 'outer declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js
new file mode 100644
index 0000000000..b88bf18fed
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-fn-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+ }
+
+ after = f;
+
+ function f() {
+ return 'outer declaration';
+ }
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'inner declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js
new file mode 100644
index 0000000000..cb3c100f7f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-no-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ [...]
+---*/
+var init;
+
+(function() {
+ var f = 123;
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js
new file mode 100644
index 0000000000..ca87f7f957
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-existing-var-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-existing-var-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'function declaration'; }
+ }
+
+ after = f;
+
+ var f = 123;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'function declaration');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js
new file mode 100644
index 0000000000..cab3d64da2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-init.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+---*/
+var init, changed;
+
+(function() {
+ init = f;
+ f = 123;
+ changed = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+
+}());
+
+assert.sameValue(init, undefined, 'binding is initialized to `undefined`');
+assert.sameValue(changed, 123, 'binding is mutable');
+assert.throws(ReferenceError, function() {
+ f;
+}, 'global binding is not created');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js
new file mode 100644
index 0000000000..93d2811ed0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-no-skip-try.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-no-skip-try.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+ );
+
+ try {
+ throw null;
+ } catch (f) {
+
+ switch (1) {
+ default:
+ function f() { return 123; }
+ }
+
+ }
+
+ assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+ );
+ assert.sameValue(f(), 123);
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js
new file mode 100644
index 0000000000..e4744d252a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-dft-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-dft-param.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when there is a default parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f = 123) {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js
new file mode 100644
index 0000000000..14f8113e92
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-block.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-block.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ {
+ let f = 123;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js
new file mode 100644
index 0000000000..0daaf4dbbe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-in.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-in.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f in { key: 0 }) {
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js
new file mode 100644
index 0000000000..ce5b5d9d3b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for-of.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for-of.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f of [0]) {
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js
new file mode 100644
index 0000000000..3fce6ca7fe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-for.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-for.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ for (let f; ; ) {
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ break;
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js
new file mode 100644
index 0000000000..41247388b1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-switch.js
@@ -0,0 +1,49 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-switch.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ switch (0) {
+ default:
+ let f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js
new file mode 100644
index 0000000000..888accb356
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err-try.js
@@ -0,0 +1,59 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err-try.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 2. If instantiatedVarNames does not contain F, then
+ a. Perform ! varEnvRec.CreateMutableBinding(F, false).
+ b. Perform varEnvRec.InitializeBinding(F, undefined).
+ c. Append F to instantiatedVarNames.
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+
+(function() {
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created prior to evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+ );
+
+ try {
+ throw {};
+ } catch ({ f }) {
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ }
+
+ assert.throws(ReferenceError, function() {
+ f;
+ }, 'An initialized binding is not created following evaluation');
+ assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+ );
+}());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js
new file mode 100644
index 0000000000..e18ab0ad06
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-early-err.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-early-err.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function() {
+ let f = 123;
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js
new file mode 100644
index 0000000000..cc12b43957
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-skip-param.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-skip-param.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Extension not observed when there is a formal parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ ii. If replacing the FunctionDeclaration f with a VariableStatement that
+ has F as a BindingIdentifier would not produce any Early Errors for
+ func and F is not an element of BoundNames of argumentsList, then
+ [...]
+---*/
+var init, after;
+
+(function(f) {
+ init = f;
+
+ switch (1) {
+ default:
+ function f() { }
+ }
+
+ after = f;
+}(123));
+
+assert.sameValue(init, 123, 'binding is not initialized to `undefined`');
+assert.sameValue(after, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js
new file mode 100644
index 0000000000..08ab434109
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/function-code/switch-dflt-func-update.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/func-update.case
+// - src/annex-b-fns/func/switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in function scope)
+esid: sec-web-compat-functiondeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.1 Changes to FunctionDeclarationInstantiation
+
+ [...]
+ 3. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ a. Let fenv be the running execution context's VariableEnvironment.
+ b. Let fenvRec be fenv's EnvironmentRecord.
+ c. Let benv be the running execution context's LexicalEnvironment.
+ d. Let benvRec be benv's EnvironmentRecord.
+ e. Let fobj be ! benvRec.GetBindingValue(F, false).
+ f. Perform ! fenvRec.SetMutableBinding(F, fobj, false).
+ g. Return NormalCompletion(empty).
+---*/
+var after;
+
+(function() {
+
+
+ switch (1) {
+ default:
+ function f() { return 'declaration'; }
+ }
+
+ after = f;
+}());
+
+assert.sameValue(typeof after, 'function');
+assert.sameValue(after(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js
new file mode 100644
index 0000000000..0e8679da87
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-block-scoping.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: A block-scoped binding is created (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+{
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..0db1e5dfe4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Does not re-initialize binding created by similar forms (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..42ac287bf8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-block-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+{
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..0e93d6138a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js
new file mode 100644
index 0000000000..b84056f1d0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-fn-update.js
@@ -0,0 +1,35 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js
new file mode 100644
index 0000000000..8f01bd2011
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-global-init.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..b5e877aca1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+{
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js
new file mode 100644
index 0000000000..01c02d7211
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-no-init.js
@@ -0,0 +1,24 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Existing variable binding is not modified (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js
new file mode 100644
index 0000000000..ed0528ff89
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-existing-var-update.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js
new file mode 100644
index 0000000000..5bee96bb60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+{
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js
new file mode 100644
index 0000000000..99f4644560
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-no-skip-try.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+{
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js
new file mode 100644
index 0000000000..97340c7ef6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-block.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..44c43c6de6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-in.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..c17c700ebe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for-of.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js
new file mode 100644
index 0000000000..cd18e31083
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-for.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+{
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..69b17807d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-switch.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js
new file mode 100644
index 0000000000..11f6f3f9f6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+{
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js
new file mode 100644
index 0000000000..bf2e8f2d78
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-skip-early-err.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+{
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js b/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js
new file mode 100644
index 0000000000..fcd9089de9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/block-decl-global-update.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/block.template
+/*---
+description: Variable binding value is updated following evaluation (Block statement in the global scope containing a function declaration)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+{
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/browser.js b/js/src/tests/test262/annexB/language/global-code/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/browser.js
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js
new file mode 100644
index 0000000000..cc91a5554b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else function _f() {}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..8c0ce24631
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..3607d616d5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..72391ceb50
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js
new file mode 100644
index 0000000000..f2361bc455
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js
new file mode 100644
index 0000000000..1782710215
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..127566889e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else function _f() {}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js
new file mode 100644
index 0000000000..0e2df04954
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js
new file mode 100644
index 0000000000..fab9e891e9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js
new file mode 100644
index 0000000000..33e4013793
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { } else function _f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js
new file mode 100644
index 0000000000..94f64755ad
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; } else function _f() {}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js
new file mode 100644
index 0000000000..35da032367
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..8b56b4ffda
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..833613ba1d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js
new file mode 100644
index 0000000000..12b21152a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { } else function _f() {}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..ae3caf3724
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js
new file mode 100644
index 0000000000..df776a337d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { } else function _f() {}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js
new file mode 100644
index 0000000000..96b6643351
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { } else function _f() {}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js
new file mode 100644
index 0000000000..00631eb1cc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-a-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-a.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; } else function _f() {}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js
new file mode 100644
index 0000000000..32fabf1305
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5013acff1d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..8586d1fab5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (false) function _f() {} else function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..fb382075d2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js
new file mode 100644
index 0000000000..20af165cb9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js
new file mode 100644
index 0000000000..1d38cf094f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..b6ac9ea951
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) function _f() {} else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js
new file mode 100644
index 0000000000..8e4b49da66
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js
new file mode 100644
index 0000000000..017c3a2df5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js
new file mode 100644
index 0000000000..1fd73e6b46
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (false) function _f() {} else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js
new file mode 100644
index 0000000000..0905343b7b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (false) function _f() {} else function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js
new file mode 100644
index 0000000000..1d2f05ebee
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..e01be3834a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..9f0f462003
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js
new file mode 100644
index 0000000000..78d783a75f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (false) function _f() {} else function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..29117eac4c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js
new file mode 100644
index 0000000000..128c69896f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (false) function _f() {} else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js
new file mode 100644
index 0000000000..4d222b42da
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (false) function _f() {} else function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js
new file mode 100644
index 0000000000..a52a234916
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-decl-b-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-decl-b.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) function _f() {} else function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js
new file mode 100644
index 0000000000..63e8de77fd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; } else ;
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..2ddbe61e82
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..ddea624e1a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..e660d2190e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js
new file mode 100644
index 0000000000..6747bc3dd6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js
new file mode 100644
index 0000000000..e3d3692688
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..51dc2295f7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; } else ;
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js
new file mode 100644
index 0000000000..b441d16b9a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js
new file mode 100644
index 0000000000..134d0331a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js
new file mode 100644
index 0000000000..95283ace21
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { } else ;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js
new file mode 100644
index 0000000000..9ddc061cba
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; } else ;
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js
new file mode 100644
index 0000000000..1b9ee82751
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..d8fbea333c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..37b8073f36
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js
new file mode 100644
index 0000000000..76fce1ad05
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { } else ;
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..02c18446ec
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js
new file mode 100644
index 0000000000..7590052baf
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { } else ;
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js
new file mode 100644
index 0000000000..cdfc04f1f3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { } else ;
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js
new file mode 100644
index 0000000000..017fb8a561
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-else-stmt-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-else-stmt.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; } else ;
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js
new file mode 100644
index 0000000000..aaa3260e4f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: A block-scoped binding is created (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (true) function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..0529a27dbb
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..2eaa65ac7e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (true) function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..6fcdab9472
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (true) function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js
new file mode 100644
index 0000000000..13efde00e9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js
new file mode 100644
index 0000000000..20ccf38a8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..476cb7d657
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (true) function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js
new file mode 100644
index 0000000000..607e4a8d5d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Existing variable binding is not modified (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js
new file mode 100644
index 0000000000..f4de295595
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js
new file mode 100644
index 0000000000..93e3e7d620
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (true) function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js
new file mode 100644
index 0000000000..51b0fa60a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (true) function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js
new file mode 100644
index 0000000000..efe8ffb573
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..8e8d983772
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..bedf210a6f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js
new file mode 100644
index 0000000000..bc51acc91c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (true) function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..42f11c6d8d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js
new file mode 100644
index 0000000000..ba28687329
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (true) function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js
new file mode 100644
index 0000000000..b89fd617c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (true) function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js
new file mode 100644
index 0000000000..9f796b80a4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-decl-no-else-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-decl-no-else.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement without an else clause in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (true) function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js
new file mode 100644
index 0000000000..82560a2ed6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-block-scoping.js
@@ -0,0 +1,53 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5619dbc4c3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-no-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..0eaf33f549
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-block-fn-update.js
@@ -0,0 +1,43 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+if (false) ; else function f() { return 'second declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..40a1c7cd33
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-no-init.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js
new file mode 100644
index 0000000000..45f31b1162
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-fn-update.js
@@ -0,0 +1,42 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js
new file mode 100644
index 0000000000..7b7d2b192d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-global-init.js
@@ -0,0 +1,57 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..32adf96121
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,58 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+if (false) ; else function f() { return 'inner declaration'; }
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js
new file mode 100644
index 0000000000..6fc5a31baa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-no-init.js
@@ -0,0 +1,31 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js
new file mode 100644
index 0000000000..12db70333c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-existing-var-update.js
@@ -0,0 +1,40 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'function declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js
new file mode 100644
index 0000000000..fdd0742747
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-init.js
@@ -0,0 +1,39 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+if (false) ; else function f() { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js
new file mode 100644
index 0000000000..cc9df07afd
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-no-skip-try.js
@@ -0,0 +1,54 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+if (false) ; else function f() { return 123; }
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js
new file mode 100644
index 0000000000..3e5c4214fa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-block.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..5003bac76f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-in.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..eb5429ed6e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for-of.js
@@ -0,0 +1,50 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js
new file mode 100644
index 0000000000..cc7fbebe59
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-for.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+if (false) ; else function f() { }
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..0a679ec65e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-switch.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js
new file mode 100644
index 0000000000..d9accdb9c2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err-try.js
@@ -0,0 +1,61 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+if (false) ; else function f() { }
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js
new file mode 100644
index 0000000000..5ab1910dbe
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-skip-early-err.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+if (false) ; else function f() { }
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js
new file mode 100644
index 0000000000..19faf6ae34
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/if-stmt-else-decl-global-update.js
@@ -0,0 +1,38 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/if-stmt-else-decl.template
+/*---
+description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in the global scope)
+esid: sec-functiondeclarations-in-ifstatement-statement-clauses
+flags: [generated, noStrict]
+info: |
+ The following rules for IfStatement augment those in 13.6:
+
+ IfStatement[Yield, Return]:
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return]
+ if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield]
+ if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield]
+
+
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+if (false) ; else function f() { return 'declaration'; }
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/shell.js b/js/src/tests/test262/annexB/language/global-code/shell.js
new file mode 100644
index 0000000000..d8963d9d60
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/shell.js
@@ -0,0 +1,14 @@
+// GENERATED, DO NOT EDIT
+// file: fnGlobalObject.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Produce a reliable global object
+defines: [fnGlobalObject]
+---*/
+
+var __globalObject = Function("return this;")();
+function fnGlobalObject() {
+ return __globalObject;
+}
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js
new file mode 100644
index 0000000000..b03d2a4dcc
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-block-scoping.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+switch (1) {
+ case 1:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..f1bbef9bc2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-no-init.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..3160336f6c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-block-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+switch (1) {
+ case 1:
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..7265812f54
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js
new file mode 100644
index 0000000000..feec1ea5f4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js
new file mode 100644
index 0000000000..b2526706ce
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..8e2679a2c4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ case 1:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js
new file mode 100644
index 0000000000..f61abec5b4
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js
new file mode 100644
index 0000000000..390f21f73c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-existing-var-update.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js
new file mode 100644
index 0000000000..7e188568aa
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js
new file mode 100644
index 0000000000..666660a8a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+switch (1) {
+ case 1:
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js
new file mode 100644
index 0000000000..51dc7e6830
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-block.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..2eb9205520
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-in.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4a6f0f0816
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for-of.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js
new file mode 100644
index 0000000000..854d86d587
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-for.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..9979075710
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-switch.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js
new file mode 100644
index 0000000000..431c89fcc6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js
new file mode 100644
index 0000000000..a85069836a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+switch (1) {
+ case 1:
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js b/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js
new file mode 100644
index 0000000000..57ca37845c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-case-global-update.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/switch-case.template
+/*---
+description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ case 1:
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js
new file mode 100644
index 0000000000..98fdab7428
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-block-scoping.js
@@ -0,0 +1,47 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-block-scoping.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ 13.2.14 Runtime Semantics: BlockDeclarationInstantiation
+
+ [...]
+ 4. For each element d in declarations do
+ a. For each element dn of the BoundNames of d do
+ i. If IsConstantDeclaration of d is true, then
+ [...]
+ ii. Else,
+ 2. Perform ! envRec.CreateMutableBinding(dn, false).
+
+ b. If d is a GeneratorDeclaration production or a FunctionDeclaration
+ production, then
+ i. Let fn be the sole element of the BoundNames of d.
+ ii. Let fo be the result of performing InstantiateFunctionObject for
+ d with argument env.
+ iii. Perform envRec.InitializeBinding(fn, fo).
+---*/
+var initialBV, currentBV;
+
+switch (1) {
+ default:
+ function f() { initialBV = f; f = 123; currentBV = f; return 'decl'; }
+}
+
+f();
+
+assert.sameValue(
+ initialBV(),
+ 'decl',
+ 'Block-scoped binding value is function object at execution time'
+);
+assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable');
+assert.sameValue(
+ f(),
+ 'decl',
+ 'Block-scoped binding is independent of outer var-scoped binding'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js
new file mode 100644
index 0000000000..5a8d67620a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-no-init.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+---*/
+assert.sameValue(f, undefined);
+
+{
+ function f() {}
+}
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js
new file mode 100644
index 0000000000..2e6ffb57a0
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-block-fn-update.js
@@ -0,0 +1,37 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-block-fn-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+{
+ function f() {
+ return 'first declaration';
+ }
+}
+
+switch (1) {
+ default:
+ function f() { return 'second declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'second declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js
new file mode 100644
index 0000000000..de237db14c
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-no-init.js
@@ -0,0 +1,26 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(F).
+ 2. If fnDefinable is true, then
+---*/
+assert.sameValue(f(), 'outer declaration');
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js
new file mode 100644
index 0000000000..bdc848d629
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-fn-update.js
@@ -0,0 +1,36 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-fn-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'inner declaration');
+
+function f() {
+ return 'outer declaration';
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js
new file mode 100644
index 0000000000..c8374585e5
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-global-init.js
@@ -0,0 +1,51 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+verifyProperty(global, 'f', {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js
new file mode 100644
index 0000000000..355df49ab1
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-non-enumerable-global-init.js
@@ -0,0 +1,52 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-non-enumerable-global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.3 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ Perform ? varEnvRec.CreateGlobalVarBinding(F, true).
+ [...]
+
+---*/
+var global = fnGlobalObject();
+Object.defineProperty(global, 'f', {
+ value: 'x',
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+$262.evalScript(`
+assert.sameValue(f, 'x');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+}, { restore: true });
+`);
+
+$262.evalScript(`
+
+switch (1) {
+ default:
+ function f() { return 'inner declaration'; }
+}
+
+`);
+
+$262.evalScript(`
+assert.sameValue(f(), 'inner declaration');
+verifyProperty(global, 'f', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js
new file mode 100644
index 0000000000..617855bc74
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-no-init.js
@@ -0,0 +1,25 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-no-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+---*/
+var f = 123;
+assert.sameValue(f, 123);
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js
new file mode 100644
index 0000000000..bc78d09851
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-existing-var-update.js
@@ -0,0 +1,34 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-existing-var-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+ [...]
+ c. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ ii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'function declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'function declaration');
+
+var f = 123;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js
new file mode 100644
index 0000000000..daac57ba41
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-init.js
@@ -0,0 +1,33 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-init.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+includes: [fnGlobalObject.js, propertyHelper.js]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If declaredFunctionOrVarNames does not contain F, then
+ i. Perform ? envRec.CreateGlobalFunctionBinding(F, undefined, false).
+ ii. Append F to declaredFunctionOrVarNames.
+ [...]
+
+---*/
+var global = fnGlobalObject();
+assert.sameValue(f, undefined, 'binding is initialized to `undefined`');
+
+verifyProperty(global, "f", {
+ enumerable: true,
+ writable: true,
+ configurable: false
+});
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js
new file mode 100644
index 0000000000..eb26d12e12
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-no-skip-try.js
@@ -0,0 +1,48 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-no-skip-try.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.sameValue(
+ f, undefined, 'Initialized binding created prior to evaluation'
+);
+
+try {
+ throw null;
+} catch (f) {
+
+switch (1) {
+ default:
+ function f() { return 123; }
+}
+
+}
+
+assert.sameValue(
+ typeof f,
+ 'function',
+ 'binding value is updated following evaluation'
+);
+assert.sameValue(f(), 123);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js
new file mode 100644
index 0000000000..8bc922544a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-block.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-block.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+{
+let f = 123;
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js
new file mode 100644
index 0000000000..bbc24f619e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-in.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-in.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f in { key: 0 }) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js
new file mode 100644
index 0000000000..4e603f783e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for-of.js
@@ -0,0 +1,44 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for-of.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f of [0]) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js
new file mode 100644
index 0000000000..0c838ac8de
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-for.js
@@ -0,0 +1,45 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-for.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (for statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+for (let f; ; ) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+ break;
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js
new file mode 100644
index 0000000000..b7ae155f9d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-switch.js
@@ -0,0 +1,46 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-switch.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+switch (0) {
+ default:
+ let f;
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js
new file mode 100644
index 0000000000..ae1530120d
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js
@@ -0,0 +1,55 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err-try.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+
+ B.3.5 VariableStatements in Catch Blocks
+
+ [...]
+ - It is a Syntax Error if any element of the BoundNames of CatchParameter
+ also occurs in the VarDeclaredNames of Block unless CatchParameter is
+ CatchParameter:BindingIdentifier and that element is only bound by a
+ VariableStatement, the VariableDeclarationList of a for statement, or the
+ ForBinding of a for-in statement.
+---*/
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created prior to evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created prior to evaluation'
+);
+
+try {
+ throw {};
+} catch ({ f }) {
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+}
+
+assert.throws(ReferenceError, function() {
+ f;
+}, 'An initialized binding is not created following evaluation');
+assert.sameValue(
+ typeof f,
+ 'undefined',
+ 'An uninitialized binding is not created following evaluation'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js
new file mode 100644
index 0000000000..f3a91763ab
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-skip-early-err.js
@@ -0,0 +1,27 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-skip-early-err.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Extension not observed when creation of variable binding would produce an early error (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ b. If replacing the FunctionDeclaration f with a VariableStatement that has
+ F as a BindingIdentifier would not produce any Early Errors for script,
+ then
+ [...]
+---*/
+let f = 123;
+assert.sameValue(f, 123, 'binding is not initialized to `undefined`');
+
+switch (1) {
+ default:
+ function f() { }
+}
+
+assert.sameValue(f, 123, 'value is not updated following evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js
new file mode 100644
index 0000000000..72fc86d451
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/global-code/switch-dflt-global-update.js
@@ -0,0 +1,32 @@
+// This file was procedurally generated from the following sources:
+// - src/annex-b-fns/global-update.case
+// - src/annex-b-fns/global/switch-dflt.template
+/*---
+description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in the global scope)
+esid: sec-web-compat-globaldeclarationinstantiation
+flags: [generated, noStrict]
+info: |
+ B.3.3.2 Changes to GlobalDeclarationInstantiation
+
+ [...]
+ e. When the FunctionDeclaration f is evaluated, perform the following steps
+ in place of the FunctionDeclaration Evaluation algorithm provided in
+ 14.1.21:
+ i. Let genv be the running execution context's VariableEnvironment.
+ ii. Let genvRec be genv's EnvironmentRecord.
+ iii. Let benv be the running execution context's LexicalEnvironment.
+ iv. Let benvRec be benv's EnvironmentRecord.
+ v. Let fobj be ! benvRec.GetBindingValue(F, false).
+ vi. Perform ? genvRec.SetMutableBinding(F, fobj, false).
+ vii. Return NormalCompletion(empty).
+---*/
+
+switch (1) {
+ default:
+ function f() { return 'declaration'; }
+}
+
+assert.sameValue(typeof f, 'function');
+assert.sameValue(f(), 'declaration');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/browser.js b/js/src/tests/test262/annexB/language/literals/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/browser.js
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/browser.js b/js/src/tests/test262/annexB/language/literals/regexp/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/browser.js
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/class-escape.js b/js/src/tests/test262/annexB/language/literals/regexp/class-escape.js
new file mode 100644
index 0000000000..dc83ac701e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/class-escape.js
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Extensions to ClassEscape
+info: |
+ ClassEscape[U] ::
+ b
+ [+U] -
+ [~U] c ClassControlLetter
+ CharacterClassEscape
+ CharacterEscape[?U]
+
+ ClassControlLetter ::
+ DecimalDigit
+ _
+
+ The production ClassEscape :: c ClassControlLetter evaluates as follows:
+
+ 1. Let ch be the character matched by ClassControlLetter.
+ 2. Let i be ch's character value.
+ 3. Let j be the remainder of dividing i by 32.
+ 4. Let d be the character whose character value is j.
+ 5. Return the CharSet containing the single character d.
+---*/
+
+var match;
+
+match = /\c0/.exec('\x0f\x10\x11');
+assert.sameValue(match, null, '\\c0 outside of CharacterClass');
+
+match = /[\c0]/.exec('\x0f\x10\x11');
+assert.sameValue(match[0], '\x10', '\\c0 within CharacterClass');
+
+match = /[\c00]+/.exec('\x0f0\x10\x11');
+assert.sameValue(match[0], '0\x10', '\\c00 within CharacterClass');
+
+match = /\c1/.exec('\x10\x11\x12');
+assert.sameValue(match, null, '\\c1 outside of CharacterClass');
+
+match = /[\c1]/.exec('\x10\x11\x12');
+assert.sameValue(match[0], '\x11', '\\c1 within CharacterClass');
+
+match = /[\c10]+/.exec('\x100\x11\x12');
+assert.sameValue(match[0], '0\x11', '\\c10 within CharacterClass');
+
+match = /\c8/.exec('\x17\x18\x19');
+assert.sameValue(match, null, '\\c8 outside of CharacterClass');
+
+match = /[\c8]/.exec('\x17\x18\x19');
+assert.sameValue(match[0], '\x18', '\\c8 within CharacterClass');
+
+match = /[\c80]+/.exec('\x170\x18\x19');
+assert.sameValue(match[0], '0\x18', '\\c80 within CharacterClass');
+
+match = /\c9/.exec('\x18\x19\x1a');
+assert.sameValue(match, null, '\\c9 outside of CharacterClass');
+
+match = /[\c9]/.exec('\x18\x19\x1a');
+assert.sameValue(match[0], '\x19', '\\c9 within CharacterClass');
+
+match = /[\c90]+/.exec('\x180\x19\x1a');
+assert.sameValue(match[0], '0\x19', '\\c90 within CharacterClass');
+
+match = /\c_/.exec('\x1e\x1f\x20');
+assert.sameValue(match, null, '\\c_ outside of CharacterClass');
+
+match = /[\c_]/.exec('\x1e\x1f\x20');
+assert.sameValue(match[0], '\x1f', '\\c_ within CharacterClass');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/extended-pattern-char.js b/js/src/tests/test262/annexB/language/literals/regexp/extended-pattern-char.js
new file mode 100644
index 0000000000..0624df6850
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/extended-pattern-char.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Extended Pattern Characters (as distinct from Pattern Characters)
+info: |
+ ExtendedPatternCharacter ::
+ SourceCharacterbut not one of ^$.*+?()[|
+
+ The production ExtendedAtom::ExtendedPatternCharacter evaluates as follows:
+
+ 1. Let ch be the character represented by ExtendedPatternCharacter.
+ 2. Let A be a one-element CharSet containing the character ch.
+ 3. Call CharacterSetMatcher(A, false) and return its Matcher result.
+---*/
+
+var match;
+
+match = /]/.exec(' ]{}');
+assert.sameValue(match[0], ']');
+
+match = /{/.exec(' ]{}');
+assert.sameValue(match[0], '{');
+
+match = /}/.exec(' ]{}');
+assert.sameValue(match[0], '}');
+
+match = /x{o}x/.exec('x{o}x');
+assert.sameValue(match[0], 'x{o}x');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/identity-escape.js b/js/src/tests/test262/annexB/language/literals/regexp/identity-escape.js
new file mode 100644
index 0000000000..b1c3a53bee
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/identity-escape.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Support for UnicodeIDContinue in IdentityEscape
+info: |
+ IdentityEscape[U] ::
+ [+U] SyntaxCharacter
+ [+U] /
+ [~U] SourceCharacter but not c
+---*/
+
+var match;
+
+match = /\C/.exec('ABCDE');
+assert.sameValue(match[0], 'C');
+
+match = /O\PQ/.exec('MNOPQRS');
+assert.sameValue(match[0], 'OPQ');
+
+match = /\8/.exec('789');
+assert.sameValue(match[0], '8');
+
+match = /7\89/.exec('67890');
+assert.sameValue(match[0], '789');
+
+match = /\9/.exec('890');
+assert.sameValue(match[0], '9');
+
+match = /8\90/.exec('78900');
+assert.sameValue(match[0], '890');
+
+match = /(.)(.)(.)(.)(.)(.)(.)(.)\8\8/.exec('0123456777');
+assert.sameValue(
+ match[0],
+ '0123456777',
+ 'DecimalEscape takes precedence over IdentityEscape (\\8)'
+);
+
+match = /(.)(.)(.)(.)(.)(.)(.)(.)(.)\9\9/.exec('01234567888');
+assert.sameValue(
+ match[0],
+ '01234567888',
+ 'DecimalEscape takes precedence over IdentityEscape (\\9)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/legacy-octal-escape.js b/js/src/tests/test262/annexB/language/literals/regexp/legacy-octal-escape.js
new file mode 100644
index 0000000000..6bba0756c3
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/legacy-octal-escape.js
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+description: Legacy Octal Escape Sequence
+info: |
+ CharacterEscape[U] ::
+ ControlEscape
+ c ControlLetter
+ 0 [lookahead ∉ DecimalDigit]
+ HexEscapeSequence
+ RegExpUnicodeEscapeSequence[?U]
+ [~U] LegacyOctalEscapeSequence
+ IdentityEscape[?U]
+
+ LegacyOctalEscapeSequence ::
+ OctalDigit [lookahead ∉ OctalDigit]
+ ZeroToThree OctalDigit [lookahead ∉ OctalDigit]
+ FourToSeven OctalDigit
+ ZeroToThree OctalDigit OctalDigit
+
+ The production CharacterEscape :: LegacyOctalEscapeSequence evaluates by
+ evaluating the SV of the LegacyOctalEscapeSequence and returning its
+ character result.
+---*/
+
+assert.sameValue(/\1/.exec('\x01')[0], '\x01', '\\1');
+assert.sameValue(/\2/.exec('\x02')[0], '\x02', '\\2');
+assert.sameValue(/\3/.exec('\x03')[0], '\x03', '\\3');
+assert.sameValue(/\4/.exec('\x04')[0], '\x04', '\\4');
+assert.sameValue(/\5/.exec('\x05')[0], '\x05', '\\5');
+assert.sameValue(/\6/.exec('\x06')[0], '\x06', '\\6');
+assert.sameValue(/\7/.exec('\x07')[0], '\x07', '\\7');
+
+assert.sameValue(/\00/.exec('\x00')[0], '\x00', '\\00');
+assert.sameValue(/\07/.exec('\x07')[0], '\x07', '\\07');
+
+assert.sameValue(/\30/.exec('\x18')[0], '\x18', '\\30');
+assert.sameValue(/\37/.exec('\x1f')[0], '\x1f', '\\37');
+
+assert.sameValue(/\40/.exec('\x20')[0], '\x20', '\\40');
+assert.sameValue(/\47/.exec('\x27')[0], '\x27', '\\47');
+
+assert.sameValue(/\70/.exec('\x38')[0], '\x38', '\\70');
+assert.sameValue(/\77/.exec('\x3f')[0], '\x3f', '\\77');
+
+// Sequence is bounded according to the String Value
+assert.sameValue(/\400/.exec('\x200')[0], '\x200', '\\400');
+assert.sameValue(/\470/.exec('\x270')[0], '\x270', '\\470');
+assert.sameValue(/\700/.exec('\x380')[0], '\x380', '\\700');
+assert.sameValue(/\770/.exec('\x3f0')[0], '\x3f0', '\\770');
+
+assert.sameValue(/\000/.exec('\x00')[0], '\x00', '\\000');
+assert.sameValue(/\007/.exec('\x07')[0], '\x07', '\\007');
+assert.sameValue(/\070/.exec('\x38')[0], '\x38', '\\070');
+
+assert.sameValue(/\300/.exec('\xc0')[0], '\xc0', '\\300');
+assert.sameValue(/\307/.exec('\xc7')[0], '\xc7', '\\307');
+assert.sameValue(/\370/.exec('\xf8')[0], '\xf8', '\\370');
+assert.sameValue(/\377/.exec('\xff')[0], '\xff', '\\377');
+
+// Sequence is 3 characters max, including leading zeros
+assert.sameValue(/\0111/.exec('\x091')[0], '\x091', '\\0111');
+assert.sameValue(/\0022/.exec('\x022')[0], '\x022', '\\0022');
+assert.sameValue(/\0003/.exec('\x003')[0], '\x003', '\\0003');
+
+var match = /(.)\1/.exec('a\x01 aa');
+assert.sameValue(
+ match[0], 'aa', 'DecimalEscape takes precedence over LegacyOctalEscapeSequence'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges-no-dash.js b/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges-no-dash.js
new file mode 100644
index 0000000000..2d0984290e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges-no-dash.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Extensions to NonemptyClassRangesNoDash production
+info: |
+ The production
+ NonemptyClassRangesNoDash::ClassAtomNoDash-ClassAtomClassRanges evaluates
+ as follows:
+
+ 1. Evaluate ClassAtomNoDash to obtain a CharSet A.
+ 2. Evaluate ClassAtom to obtain a CharSet B.
+ 3. Evaluate ClassRanges to obtain a CharSet C.
+ 4. Call CharacterRangeOrUnion(A, B) and let D be the resulting CharSet.
+ 5. Return the union of CharSets D and C.
+
+ B.1.4.1.1 Runtime Semantics: CharacterRangeOrUnion Abstract Operation
+
+ 1. If Unicode is false, then
+ a. If A does not contain exactly one character or B does not contain
+ exactly one character, then
+ i. Let C be the CharSet containing the single character - U+002D
+ (HYPHEN-MINUS).
+ ii. Return the union of CharSets A, B and C.
+ 2. Return CharacterRange(A, B).
+---*/
+
+var match;
+
+match = /[\d-a]+/.exec(':a0123456789-:');
+assert.sameValue(match[0], 'a0123456789-');
+
+match = /[\d-az]+/.exec(':a0123456789z-:');
+assert.sameValue(match[0], 'a0123456789z-');
+
+match = /[%-\d]+/.exec('&%0123456789-&');
+assert.sameValue(match[0], '%0123456789-');
+
+match = /[%-\dz]+/.exec('&%0123456789z-&');
+assert.sameValue(match[0], '%0123456789z-');
+
+match = /[\s-\d]+/.exec('& \t0123456789-&');
+assert.sameValue(match[0], ' \t0123456789-');
+
+match = /[\s-\dz]+/.exec('& \t0123456789z-&');
+assert.sameValue(match[0], ' \t0123456789z-');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges.js b/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges.js
new file mode 100644
index 0000000000..7aad0745ee
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/non-empty-class-ranges.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Extensions to NonemptyClassRanges production
+info: |
+ The production NonemptyClassRanges :: ClassAtom-ClassAtom ClassRanges
+ evaluates as follows:
+
+ 1. Evaluate the first ClassAtom to obtain a CharSet A.
+ 2. Evaluate the second ClassAtom to obtain a CharSet B.
+ 3. Evaluate ClassRanges to obtain a CharSet C.
+ 4. Call CharacterRangeOrUnion(A, B) and let D be the resulting CharSet.
+ 5. Return the union of CharSets D and C.
+
+ B.1.4.1.1 Runtime Semantics: CharacterRangeOrUnion Abstract Operation
+
+ 1. If Unicode is false, then
+ a. If A does not contain exactly one character or B does not contain
+ exactly one character, then
+ i. Let C be the CharSet containing the single character - U+002D
+ (HYPHEN-MINUS).
+ ii. Return the union of CharSets A, B and C.
+ 2. Return CharacterRange(A, B).
+---*/
+
+var match;
+
+match = /[--\d]+/.exec('.-0123456789-.');
+assert.sameValue(match[0], '-0123456789-');
+
+match = /[--\dz]+/.exec('.-0123456789z-.');
+assert.sameValue(match[0], '-0123456789z-');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-followed-by.js b/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-followed-by.js
new file mode 100644
index 0000000000..4e09b24a95
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-followed-by.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Quantifiable assertions `?=` ("followed by")
+info: |
+ Term[U] ::
+ [~U] QuantifiableAssertion Quantifier
+
+ QuantifiableAssertion ::
+ ( ?= Disjunction )
+ ( ?! Disjunction )
+
+ The production Term::QuantifiableAssertionQuantifier evaluates the same as
+ the production Term::AtomQuantifier but with QuantifiableAssertion
+ substituted for Atom.
+
+ The production Assertion::QuantifiableAssertion evaluates by evaluating
+ QuantifiableAssertion to obtain a Matcher and returning that Matcher.
+
+ Assertion (21.2.2.6) evaluation rules for the Assertion::(?=Disjunction)
+ and Assertion::(?!Disjunction) productions are also used for the
+ QuantifiableAssertion productions, but with QuantifiableAssertion
+ substituted for Assertion.
+---*/
+
+var match;
+
+match = /.(?=Z)*/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'a', 'quantifier: *');
+
+match = /.(?=Z)+/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: +');
+
+match = /.(?=Z)?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'a', 'quantifier: ?');
+
+match = /.(?=Z){2}/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: { DecimalDigits }');
+
+match = /.(?=Z){2,}/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: { DecimalDigits , }');
+
+match = /.(?=Z){2,3}/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(
+ match[0], 'b', 'quantifier: { DecimalDigits , DecimalDigits }'
+);
+
+match = /.(?=Z)*?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'a', 'quantifier: * ?');
+
+match = /.(?=Z)+?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: + ?');
+
+match = /.(?=Z)??/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'a', 'quantifier: ? ?');
+
+match = /.(?=Z){2}?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: { DecimalDigits } ?');
+
+match = /.(?=Z){2,}?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(match[0], 'b', 'quantifier: { DecimalDigits , } ?');
+
+match = /.(?=Z){2,3}?/.exec('a bZ cZZ dZZZ eZZZZ');
+assert.sameValue(
+ match[0], 'b', 'quantifier: { DecimalDigits , DecimalDigits } ?'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-not-followed-by.js b/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-not-followed-by.js
new file mode 100644
index 0000000000..2b92affa3a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/quantifiable-assertion-not-followed-by.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-regular-expressions-patterns
+es6id: B.1.4
+description: Quantifiable assertions `?!` ("not followed by")
+info: |
+ Term[U] ::
+ [~U] QuantifiableAssertion Quantifier
+
+ QuantifiableAssertion::
+ ( ?= Disjunction )
+ ( ?! Disjunction )
+
+ The production Term::QuantifiableAssertionQuantifier evaluates the same as
+ the production Term::AtomQuantifier but with QuantifiableAssertion
+ substituted for Atom.
+
+ The production Assertion::QuantifiableAssertion evaluates by evaluating
+ QuantifiableAssertion to obtain a Matcher and returning that Matcher.
+
+ Assertion (21.2.2.6) evaluation rules for the Assertion::(?=Disjunction)
+ and Assertion::(?!Disjunction) productions are also used for the
+ QuantifiableAssertion productions, but with QuantifiableAssertion
+ substituted for Assertion.
+---*/
+
+var match;
+
+match = /[a-e](?!Z)*/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'a', 'quantifier: *');
+
+match = /[a-e](?!Z)+/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: +');
+
+match = /[a-e](?!Z)?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'a', 'quantifier: ?');
+
+match = /[a-e](?!Z){2}/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: { DecimalDigits }');
+
+match = /[a-e](?!Z){2,}/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: { DecimalDigits , }');
+
+match = /[a-e](?!Z){2,3}/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(
+ match[0], 'e', 'quantifier: { DecimalDigits , DecimalDigits }'
+);
+
+match = /[a-e](?!Z)*?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'a', 'quantifier: * ?');
+
+match = /[a-e](?!Z)+?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: + ?');
+
+match = /[a-e](?!Z)??/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'a', 'quantifier: ? ?');
+
+match = /[a-e](?!Z){2}?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: { DecimalDigits } ?');
+
+match = /[a-e](?!Z){2,}?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(match[0], 'e', 'quantifier: { DecimalDigits , } ?');
+
+match = /[a-e](?!Z){2,3}?/.exec('aZZZZ bZZZ cZZ dZ e');
+assert.sameValue(
+ match[0], 'e', 'quantifier: { DecimalDigits , DecimalDigits } ?'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/literals/regexp/shell.js b/js/src/tests/test262/annexB/language/literals/regexp/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/regexp/shell.js
diff --git a/js/src/tests/test262/annexB/language/literals/shell.js b/js/src/tests/test262/annexB/language/literals/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/literals/shell.js
diff --git a/js/src/tests/test262/annexB/language/shell.js b/js/src/tests/test262/annexB/language/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/browser.js b/js/src/tests/test262/annexB/language/statements/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/class/browser.js b/js/src/tests/test262/annexB/language/statements/class/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/class/shell.js b/js/src/tests/test262/annexB/language/statements/class/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/class/subclass/browser.js b/js/src/tests/test262/annexB/language/statements/class/subclass/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/subclass/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/class/subclass/shell.js b/js/src/tests/test262/annexB/language/statements/class/subclass/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/subclass/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-emulates-undefined.js
new file mode 100644
index 0000000000..245e7d402b
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-emulates-undefined.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-runtime-semantics-classdefinitionevaluation
+description: >
+ [[IsHTMLDDA]] object as superclass: `null` check uses strict equality.
+ IsConstructor check is performed before "prototype" lookup.
+info: |
+ ClassDefinitionEvaluation
+
+ [...]
+ 5. Else,
+ [...]
+ d. Let superclass be ? GetValue(superclassRef).
+ e. If superclass is null, then
+ [...]
+ f. Else if IsConstructor(superclass) is false, throw a TypeError exception.
+features: [class, IsHTMLDDA]
+---*/
+
+var superclass = $262.IsHTMLDDA;
+var prototypeGets = 0;
+Object.defineProperty(superclass, "prototype", {
+ get: function() {
+ prototypeGets += 1;
+ },
+});
+
+assert.throws(TypeError, function() {
+ class C extends superclass {}
+});
+
+assert.sameValue(prototypeGets, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-prototype-emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-prototype-emulates-undefined.js
new file mode 100644
index 0000000000..542dbb0756
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/class/subclass/superclass-prototype-emulates-undefined.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-runtime-semantics-classdefinitionevaluation
+description: >
+ [[IsHTMLDDA]] object as "prototype" of superclass: `null` check uses strict equality.
+info: |
+ ClassDefinitionEvaluation
+
+ [...]
+ 5. Else,
+ [...]
+ g. Else,
+ i. Let protoParent be ? Get(superclass, "prototype").
+ ii. If Type(protoParent) is neither Object nor Null, throw a TypeError exception.
+ iii. Let constructorParent be superclass.
+ 6. Let proto be OrdinaryObjectCreate(protoParent).
+ [...]
+features: [class, IsHTMLDDA]
+---*/
+
+function Superclass() {}
+Superclass.prototype = $262.IsHTMLDDA;
+
+class C extends Superclass {}
+var c = new C();
+
+assert(c instanceof C);
+assert(c instanceof Superclass);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/const/browser.js b/js/src/tests/test262/annexB/language/statements/const/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/const/dstr/array-pattern-emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/const/dstr/array-pattern-emulates-undefined.js
new file mode 100644
index 0000000000..ebc12e7a3a
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/dstr/array-pattern-emulates-undefined.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-destructuring-binding-patterns-runtime-semantics-bindinginitialization
+description: >
+ Destructuring initializer is not evaluated when value is an object
+ with [[IsHTMLDDA]] internal slot.
+info: |
+ BindingPattern : ArrayBindingPattern
+
+ 1. Let iteratorRecord be ? GetIterator(value).
+ 2. Let result be IteratorBindingInitialization of ArrayBindingPattern with arguments
+ iteratorRecord and environment.
+ 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
+ 4. Return result.
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer[opt]
+
+ [...]
+ 5. If Initializer is present and v is undefined, then
+ [...]
+ 6. If environment is undefined, return ? PutValue(lhs, v).
+features: [destructuring-binding, IsHTMLDDA]
+---*/
+
+let initCount = 0;
+const counter = function() {
+ initCount += 1;
+};
+
+const IsHTMLDDA = $262.IsHTMLDDA;
+const [x = counter()] = [IsHTMLDDA];
+
+assert.sameValue(x, IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/const/dstr/browser.js b/js/src/tests/test262/annexB/language/statements/const/dstr/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/dstr/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/const/dstr/object-pattern-emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/const/dstr/object-pattern-emulates-undefined.js
new file mode 100644
index 0000000000..5db5558567
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/dstr/object-pattern-emulates-undefined.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-destructuring-binding-patterns-runtime-semantics-bindinginitialization
+description: >
+ Destructuring initializer is not evaluated when value is an object
+ with [[IsHTMLDDA]] internal slot.
+info: |
+ BindingPattern : ObjectBindingPattern
+
+ 1. Perform ? RequireObjectCoercible(value).
+ 2. Return the result of performing BindingInitialization for
+ ObjectBindingPattern using value and environment as arguments.
+
+ Runtime Semantics: KeyedBindingInitialization
+
+ SingleNameBinding : BindingIdentifier Initializer[opt]
+
+ [...]
+ 4. If Initializer is present and v is undefined, then
+ [...]
+ 5. If environment is undefined, return ? PutValue(lhs, v).
+features: [destructuring-binding, IsHTMLDDA]
+---*/
+
+let initCount = 0;
+const counter = function() {
+ initCount += 1;
+};
+
+const IsHTMLDDA = $262.IsHTMLDDA;
+const {x = counter()} = {x: IsHTMLDDA};
+
+assert.sameValue(x, IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/const/dstr/shell.js b/js/src/tests/test262/annexB/language/statements/const/dstr/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/dstr/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/const/shell.js b/js/src/tests/test262/annexB/language/statements/const/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/const/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-await-of/browser.js b/js/src/tests/test262/annexB/language/statements/for-await-of/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-await-of/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-await-of/iterator-close-return-emulates-undefined-throws-when-called.js b/js/src/tests/test262/annexB/language/statements/for-await-of/iterator-close-return-emulates-undefined-throws-when-called.js
new file mode 100644
index 0000000000..21860d325e
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-await-of/iterator-close-return-emulates-undefined-throws-when-called.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-getiterator
+description: >
+ `GetIterator(obj, ~async~)` must attempt to call `obj[@@asyncIterator]` when
+ that value is an object with an [[IsHTMLDDA]] internal slot, not act as if
+ the value were `undefined`.
+features: [async-iteration, IsHTMLDDA]
+flags: [async]
+---*/
+
+async function f() {
+ var IsHTMLDDA = $262.IsHTMLDDA;
+ var iter = {
+ [Symbol.asyncIterator]: IsHTMLDDA,
+ get [Symbol.iterator]() {
+ throw new Test262Error("shouldn't touch Symbol.iterator");
+ },
+ };
+
+ // `IsHTMLDDA` is called here with `iter` as `this` and no arguments, and it's
+ // expected to return `null` under these conditions. Then the iteration
+ // protocol throws a `TypeError` because `null` isn't an object.
+ for await (var x of iter)
+ return "for-await-of body shouldn't be reached";
+
+ return "should have failed earlier";
+}
+
+f().then($DONE,
+ function (e) {
+ assert.sameValue(e.constructor, TypeError,
+ "expected TypeError because " +
+ "`iter[Symbol.asyncIterator]() returned a " +
+ "non-object: " + e);
+ })
+ .then($DONE, $DONE);
diff --git a/js/src/tests/test262/annexB/language/statements/for-await-of/shell.js b/js/src/tests/test262/annexB/language/statements/for-await-of/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-await-of/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/bare-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/bare-initializer.js
new file mode 100644
index 0000000000..6c9ecce1ea
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/bare-initializer.js
@@ -0,0 +1,16 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in heads prohibit AssignmentExpressions
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+var a;
+
+for (a = 0 in {});
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/browser.js b/js/src/tests/test262/annexB/language/statements/for-in/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/const-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/const-initializer.js
new file mode 100644
index 0000000000..940a14be19
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/const-initializer.js
@@ -0,0 +1,16 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers with const are prohibited
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (const a = 0 in {});
+
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/let-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/let-initializer.js
new file mode 100644
index 0000000000..ff14bf6542
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/let-initializer.js
@@ -0,0 +1,16 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers with let are prohibited
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (let a = 0 in {});
+
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/nonstrict-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/nonstrict-initializer.js
new file mode 100644
index 0000000000..10d492827f
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/nonstrict-initializer.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers in nonstrict mode
+flags: [noStrict]
+---*/
+(function() {
+ var effects = 0;
+ for (var a = ++effects in {});
+ assert.sameValue(effects, 1);
+})();
+
+
+(function() {
+ var stored;
+ for (var a = 0 in stored = a, {});
+ assert.sameValue(stored, 0);
+})();
+
+
+(function() {
+ for (var a = 0 in {});
+ assert.sameValue(a, 0);
+})();
+
+
+(function() {
+ var effects = 0;
+ var iterations = 0;
+ var stored;
+ for (var a = (++effects, -1) in stored = a, {a: 0, b: 1, c: 2}) {
+ ++iterations;
+ }
+ assert.sameValue(stored, -1, "Initialized value should be available to RHS");
+ assert.sameValue(effects, 1, "Initializer should only be executed once");
+ assert.sameValue(iterations, 3, "Loop body should be executed the appropriate number of times");
+})();
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/shell.js b/js/src/tests/test262/annexB/language/statements/for-in/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/strict-initializer-strict.js b/js/src/tests/test262/annexB/language/statements/for-in/strict-initializer-strict.js
new file mode 100644
index 0000000000..afc84b3489
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/strict-initializer-strict.js
@@ -0,0 +1,17 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers in strict mode are prohibited
+negative:
+ phase: parse
+ type: SyntaxError
+flags: [onlyStrict]
+---*/
+
+$DONOTEVALUATE();
+
+for (var a = 0 in {});
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/var-arraybindingpattern-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/var-arraybindingpattern-initializer.js
new file mode 100644
index 0000000000..9857e0fcf6
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/var-arraybindingpattern-initializer.js
@@ -0,0 +1,15 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers with ArrayBindingPatterns are always prohibited
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var [a] = 0 in {});
diff --git a/js/src/tests/test262/annexB/language/statements/for-in/var-objectbindingpattern-initializer.js b/js/src/tests/test262/annexB/language/statements/for-in/var-objectbindingpattern-initializer.js
new file mode 100644
index 0000000000..dfa077eade
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-in/var-objectbindingpattern-initializer.js
@@ -0,0 +1,16 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-initializers-in-forin-statement-heads
+description: >
+ for-in initializers with ObjectBindingPattern are always prohibited
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var {a} = 0 in {});
+
diff --git a/js/src/tests/test262/annexB/language/statements/for-of/browser.js b/js/src/tests/test262/annexB/language/statements/for-of/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-of/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js b/js/src/tests/test262/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js
new file mode 100644
index 0000000000..6a81a3ec29
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-iteratorclose
+description: >
+ If <iterator>.return is an object emulating `undefined` (e.g. `document.all`
+ in browsers), it shouldn't be treated as if it were actually `undefined`.
+features: [generators, IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+var iter = {
+ [Symbol.iterator]() { return this; },
+ next() { return {}; },
+ return: IsHTMLDDA,
+};
+
+assert.throws(TypeError, function() {
+ // `IsHTMLDDA` is called here with `iter` as `this` and no arguments, and it's
+ // specified to return `null` under these conditions. Then the iteration
+ // protocol throws a `TypeError` because `null` isn't an object.
+ for (var x of iter)
+ break;
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/for-of/shell.js b/js/src/tests/test262/annexB/language/statements/for-of/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/for-of/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/function/browser.js b/js/src/tests/test262/annexB/language/statements/function/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/function/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/function/default-parameters-emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/function/default-parameters-emulates-undefined.js
new file mode 100644
index 0000000000..fac48fab79
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/function/default-parameters-emulates-undefined.js
@@ -0,0 +1,74 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
+description: >
+ Initializer is not evaluated when argument is an object with
+ [[IsHTMLDDA]] internal slot.
+info: |
+ FunctionDeclaration :
+ function BindingIdentifier ( FormalParameters ) { FunctionBody }
+
+ [...]
+ 3. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody,
+ scope, strict).
+ [...]
+
+ [[Call]] ( thisArgument, argumentsList)
+
+ [...]
+ 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+ [...]
+
+ OrdinaryCallEvaluateBody ( F, argumentsList )
+
+ 1. Let status be FunctionDeclarationInstantiation(F, argumentsList).
+ [...]
+
+ FunctionDeclarationInstantiation(func, argumentsList)
+
+ [...]
+ 23. Let iteratorRecord be Record {[[iterator]]:
+ CreateListIterator(argumentsList), [[done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ b. Let formalStatus be IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+
+ Runtime Semantics: IteratorBindingInitialization
+
+ FormalsList : FormalsList , FormalParameter
+
+ [...]
+ 23. Let iteratorRecord be Record {[[Iterator]]:
+ CreateListIterator(argumentsList), [[Done]]: false}.
+ 24. If hasDuplicates is true, then
+ [...]
+ 25. Else,
+ a. Perform ? IteratorBindingInitialization for formals with
+ iteratorRecord and env as arguments.
+ [...]
+features: [default-parameters, IsHTMLDDA]
+---*/
+
+let initCount = 0;
+const counter = function() {
+ initCount += 1;
+};
+
+const arrow = (x = counter()) => x;
+const IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(arrow(IsHTMLDDA), IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+function fn(x, y = counter()) {
+ return y;
+}
+
+assert.sameValue(fn(1, IsHTMLDDA), IsHTMLDDA);
+assert.sameValue(initCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/function/shell.js b/js/src/tests/test262/annexB/language/statements/function/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/function/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/if/browser.js b/js/src/tests/test262/annexB/language/statements/if/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/if/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/if/emulated-undefined.js b/js/src/tests/test262/annexB/language/statements/if/emulated-undefined.js
new file mode 100644
index 0000000000..46f73419f8
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/if/emulated-undefined.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-if-statement-runtime-semantics-evaluation
+description: >
+ ToBoolean returns `false` for [[IsHTMLDDA]] object; first Statement is not evaluated.
+info: |
+ IfStatement : if ( Expression ) Statement else Statement
+
+ 1. Let exprRef be the result of evaluating Expression.
+ 2. Let exprValue be ! ToBoolean(? GetValue(exprRef)).
+ 3. If exprValue is true, then
+ [...]
+ 4. Else,
+ a. Let stmtCompletion be the result of evaluating the second Statement.
+
+ The [[IsHTMLDDA]] Internal Slot / Changes to ToBoolean
+
+ 1. If argument has an [[IsHTMLDDA]] internal slot, return false.
+ 2. Return true.
+features: [IsHTMLDDA]
+---*/
+
+var result = false;
+if ($262.IsHTMLDDA) {
+ throw new Test262Error("unreachable");
+} else {
+ result = true;
+}
+
+assert(result);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/if/shell.js b/js/src/tests/test262/annexB/language/statements/if/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/if/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/labeled/browser.js b/js/src/tests/test262/annexB/language/statements/labeled/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/labeled/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/labeled/function-declaration.js b/js/src/tests/test262/annexB/language/statements/labeled/function-declaration.js
new file mode 100644
index 0000000000..ff3e9cf207
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/labeled/function-declaration.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2011 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.1
+description: >
+ function declarations in statement position in non-strict mode:
+ label: Statement
+flags: [noStrict]
+---*/
+label: function g() {}
+
+label1: label2: function f() {}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/labeled/shell.js b/js/src/tests/test262/annexB/language/statements/labeled/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/labeled/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/shell.js b/js/src/tests/test262/annexB/language/statements/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/switch/browser.js b/js/src/tests/test262/annexB/language/statements/switch/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/switch/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/switch/emulates-undefined.js b/js/src/tests/test262/annexB/language/statements/switch/emulates-undefined.js
new file mode 100644
index 0000000000..a0452c5454
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/switch/emulates-undefined.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-runtime-semantics-caseclauseisselected
+description: >
+ `switch` statement uses Strict Equality Comparison,
+ which doesn't special-case [[IsHTMLDDA]] objects.
+info: |
+ Runtime Semantics: CaseClauseIsSelected ( C, input )
+
+ [...]
+ 4. Return the result of performing Strict Equality Comparison input === clauseSelector.
+
+ Strict Equality Comparison
+
+ 1. If Type(x) is different from Type(y), return false.
+features: [IsHTMLDDA]
+---*/
+
+var IsHTMLDDA = $262.IsHTMLDDA;
+
+assert.sameValue(
+ (function() {
+ switch (IsHTMLDDA) {
+ case undefined: return 1;
+ case null: return 2;
+ case IsHTMLDDA: return 3;
+ }
+ })(),
+ 3
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/switch/shell.js b/js/src/tests/test262/annexB/language/statements/switch/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/switch/shell.js
diff --git a/js/src/tests/test262/annexB/language/statements/try/browser.js b/js/src/tests/test262/annexB/language/statements/try/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/browser.js
diff --git a/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-in-var.js b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-in-var.js
new file mode 100644
index 0000000000..2a8efd5591
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-in-var.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-variablestatements-in-catch-blocks
+es6id: B.3.5
+description: Re-declaration of catch parameter (for-in statement)
+info: |
+ 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.
+---*/
+
+var before, during, after;
+
+try {
+ throw 'exception';
+} catch (err) {
+ before = err;
+ for (var err in { propertyName: null }) {
+ during = err;
+ }
+ after = err;
+}
+
+assert.sameValue(before, 'exception');
+assert.sameValue(during, 'propertyName', 'during loop body evaluation');
+assert.sameValue(after, 'propertyName', 'after loop body evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-of-var.js b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-of-var.js
new file mode 100644
index 0000000000..2a9da1e1f9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-of-var.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Ross Kirsling
+esid: sec-variablestatements-in-catch-blocks
+description: Re-declaration of catch parameter (for-of statement)
+info: |
+ 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.
+---*/
+
+var before, during, after;
+
+try {
+ throw 'exception';
+} catch (err) {
+ before = err;
+ for (var err of [2]) {
+ during = err;
+ }
+ after = err;
+}
+
+assert.sameValue(before, 'exception');
+assert.sameValue(during, 2, 'during loop body evaluation');
+assert.sameValue(after, 2, 'after loop body evaluation');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-var.js b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-var.js
new file mode 100644
index 0000000000..0ca15f0af9
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-for-var.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-variablestatements-in-catch-blocks
+es6id: B.3.5
+description: Re-declaration of catch parameter (for statement)
+info: |
+ 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.
+---*/
+
+var before, during, after;
+
+try {
+ throw 'exception';
+} catch (err) {
+ before = err;
+ for (var err = 'loop initializer'; err !== 'increment'; err = 'increment') {
+ during = err;
+ }
+ after = err;
+}
+
+assert.sameValue(before, 'exception');
+assert.sameValue(during, 'loop initializer');
+assert.sameValue(after, 'increment');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement-captured.js b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement-captured.js
new file mode 100644
index 0000000000..b9865d0a03
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement-captured.js
@@ -0,0 +1,23 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.14-2
+es6id: B.3.5
+description: >
+ catch doesn't change declaration scope - var initializer in catch
+ with same name as catch parameter changes parameter
+---*/
+
+ function capturedFoo() {return foo};
+ foo = "prior to throw";
+ try {
+ throw new Error();
+ }
+ catch (foo) {
+ var foo = "initializer in catch";
+ }
+
+assert.sameValue(capturedFoo(), "prior to throw");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement.js b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement.js
new file mode 100644
index 0000000000..6cfcbde4f7
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/catch-redeclared-var-statement.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.14-1
+es6id: B.3.5
+description: >
+ catch doesn't change declaration scope - var initializer in catch
+ with same name as catch parameter changes parameter
+---*/
+
+ foo = "prior to throw";
+ try {
+ throw new Error();
+ }
+ catch (foo) {
+ var foo = "initializer in catch";
+ }
+
+assert.sameValue(foo, "prior to throw");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/annexB/language/statements/try/shell.js b/js/src/tests/test262/annexB/language/statements/try/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/language/statements/try/shell.js
diff --git a/js/src/tests/test262/annexB/shell.js b/js/src/tests/test262/annexB/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/annexB/shell.js