diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/annexB/language | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/annexB/language')
909 files changed, 36039 insertions, 0 deletions
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 |