diff options
Diffstat (limited to 'js/src/tests/test262/annexB/language/eval-code')
474 files changed, 20249 insertions, 0 deletions
diff --git a/js/src/tests/test262/annexB/language/eval-code/browser.js b/js/src/tests/test262/annexB/language/eval-code/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/browser.js diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js b/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js new file mode 100644 index 0000000000..4260564232 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/block-decl-nostrict.js @@ -0,0 +1,29 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-web-compat-evaldeclarationinstantiation +description: > + AnnexB extension not honored in strict mode, Block statement + in eval code containing a function declaration +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + 1. If strict is false, then + ... + +flags: [noStrict] +---*/ + +var err; + +eval('{ function f() {} }'); + +try { + f; +} catch (exception) { + err = exception; +} + +assert.sameValue(err, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/browser.js b/js/src/tests/test262/annexB/language/eval-code/direct/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/browser.js diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js new file mode 100644 index 0000000000..27dde2f65f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: A block-scoped binding is created (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + '{ function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } }varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..68ddb06e7c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,29 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Does not re-initialize binding created by similar forms (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }{ function f() { } }' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..a2644fcd64 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-block-fn-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Variable-scoped binding is updated (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }{ function f() { return "second declaration"; } }updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..2daa5c9126 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Existing variable binding is not modified (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;{ function f() { return "inner declaration"; } }function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..bae56d9b36 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-fn-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + '{ function f() { return "inner declaration"; } }after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..958db3cd13 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-no-init.js @@ -0,0 +1,26 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Existing variable binding is not modified (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;{ function f() { } }' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js new file mode 100644 index 0000000000..34f4301f6c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-existing-var-update.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + '{ function f() { return "function declaration"; } }after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js new file mode 100644 index 0000000000..301da9a25a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;{ function f() { } }' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js new file mode 100644 index 0000000000..203f4619cc --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension observed when there is a formal parameter with the same name (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;{ function f() { } }after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js new file mode 100644 index 0000000000..4f4e34e5fe --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {{ function f() { return 123; } }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..ab535b814d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..c2374ae895 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..dc7da05847 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-of.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..d16957c668 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {{ function f() { } }break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..1f7debf9dd --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-switch.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..ca87e65bd0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js new file mode 100644 index 0000000000..db50751ee7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js @@ -0,0 +1,29 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;{ function f() { } }after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js new file mode 100644 index 0000000000..b48ae1660e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-block.template +/*--- +description: Variable binding value is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + '{ function f() { return "declaration"; } }after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js new file mode 100644 index 0000000000..ab4f4c787b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else function _f() {}varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..608471685f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }if (true) function f() { } else function _f() {}' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..78075b67a0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-block-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }if (true) function f() { return "second declaration"; } else function _f() {}updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..b122a09227 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-no-init.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;if (true) function f() { return "inner declaration"; } else function _f() {}function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..6a8a3dc2de --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "inner declaration"; } else function _f() {}after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..c8a445bde3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;if (true) function f() { } else function _f() {}' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js new file mode 100644 index 0000000000..b91fe29ce9 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-existing-var-update.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "function declaration"; } else function _f() {}after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js new file mode 100644 index 0000000000..7f617fda59 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;if (true) function f() { } else function _f() {}' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js new file mode 100644 index 0000000000..ce5e20cfae --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;if (true) function f() { } else function _f() {}after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js new file mode 100644 index 0000000000..f64640a045 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; } else function _f() {}}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..211a3ce0c3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..b1636d30ac --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..415575514b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-of.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..df7be27661 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {if (true) function f() { } else function _f() {}break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..7c13f0bf39 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-switch.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..867bd698a8 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js @@ -0,0 +1,62 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js new file mode 100644 index 0000000000..5ace0cefe2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;if (true) function f() { } else function _f() {}after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js new file mode 100644 index 0000000000..4ce12a85c2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "declaration"; } else function _f() {}after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js new file mode 100644 index 0000000000..6a44335315 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..c965768369 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }if (false) function _f() {} else function f() { }' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..4d2f769900 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-block-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }if (false) function _f() {} else function f() { return "second declaration"; }updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..52b85a93cc --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-no-init.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;if (false) function _f() {} else function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..20940b96f5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) function _f() {} else function f() { return "inner declaration"; }after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..d717d59719 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;if (false) function _f() {} else function f() { }' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js new file mode 100644 index 0000000000..0f83c2e3cf --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-existing-var-update.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) function _f() {} else function f() { return "function declaration"; }after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js new file mode 100644 index 0000000000..f4082faa35 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;if (false) function _f() {} else function f() { }' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js new file mode 100644 index 0000000000..f53002a4c6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;if (false) function _f() {} else function f() { }after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js new file mode 100644 index 0000000000..fbae9f3576 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (false) function _f() {} else function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..9c3bbfc98b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..1379520ad3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..4371c9bf80 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-of.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..2464a27f3b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {if (false) function _f() {} else function f() { }break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..ababc66716 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-switch.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..5b51ba6fca --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js @@ -0,0 +1,62 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js new file mode 100644 index 0000000000..96807f992e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;if (false) function _f() {} else function f() { }after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js new file mode 100644 index 0000000000..59d3d0bc2c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) function _f() {} else function f() { return "declaration"; }after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js new file mode 100644 index 0000000000..4187c63e20 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else ;varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..354fe9d6bb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }if (true) function f() { } else ;' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..fd03957d8b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-block-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }if (true) function f() { return "second declaration"; } else ;updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..c6c0e2d941 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-no-init.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;if (true) function f() { return "inner declaration"; } else ;function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..8705895578 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "inner declaration"; } else ;after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..206aa99fd8 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;if (true) function f() { } else ;' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js new file mode 100644 index 0000000000..cddd42ce9f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-existing-var-update.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "function declaration"; } else ;after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js new file mode 100644 index 0000000000..30770f1d92 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;if (true) function f() { } else ;' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js new file mode 100644 index 0000000000..5df8c42e6b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;if (true) function f() { } else ;after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js new file mode 100644 index 0000000000..080bd25244 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; } else ;}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..b0cc6e463b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..5afbf9a836 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..0dd9a09a45 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-of.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..dc649e4656 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {if (true) function f() { } else ;break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..0c36fb6f95 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-switch.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..ea403cb698 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js @@ -0,0 +1,62 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js new file mode 100644 index 0000000000..308c01276a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;if (true) function f() { } else ;after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js new file mode 100644 index 0000000000..27a7bbb3e2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-else-stmt.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "declaration"; } else ;after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js new file mode 100644 index 0000000000..d660e42edb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: A block-scoped binding is created (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..e0a6b3c8ad --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }if (true) function f() { }' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..72b2d2e2be --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-block-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }if (true) function f() { return "second declaration"; }updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..85066a3b78 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-no-init.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Existing variable binding is not modified (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;if (true) function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..9ffa96945e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "inner declaration"; }after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..758a8c545f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Existing variable binding is not modified (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;if (true) function f() { }' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js new file mode 100644 index 0000000000..a8a76bdbcc --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-existing-var-update.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "function declaration"; }after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js new file mode 100644 index 0000000000..2eee349098 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;if (true) function f() { }' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js new file mode 100644 index 0000000000..eb72a10dd9 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension observed when there is a formal parameter with the same name (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;if (true) function f() { }after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js new file mode 100644 index 0000000000..e93cd1eada --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..3819ca1bf1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..75600f772f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..667652faf1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-of.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..6580695602 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {if (true) function f() { }break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..d582221cc6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-switch.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..84e5447a1a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js @@ -0,0 +1,62 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js new file mode 100644 index 0000000000..ee99ef56bd --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;if (true) function f() { }after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js new file mode 100644 index 0000000000..aa5a7629c7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-if-decl-no-else.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (true) function f() { return "declaration"; }after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js new file mode 100644 index 0000000000..21aa62c841 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..8d153d8e32 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }if (false) ; else function f() { }' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..28076cdfd5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-block-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }if (false) ; else function f() { return "second declaration"; }updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..149b57f16c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-no-init.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;if (false) ; else function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..4c55632cc3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-fn-update.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) ; else function f() { return "inner declaration"; }after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..2ddea80824 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-no-init.js @@ -0,0 +1,35 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;if (false) ; else function f() { }' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js new file mode 100644 index 0000000000..9bcc71893c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-existing-var-update.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) ; else function f() { return "function declaration"; }after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js new file mode 100644 index 0000000000..10ae99630d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;if (false) ; else function f() { }' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js new file mode 100644 index 0000000000..b46e821b6b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension observed when there is a formal parameter with the same name (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;if (false) ; else function f() { }after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js new file mode 100644 index 0000000000..f4978f2488 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (false) ; else function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..de5cb215c8 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..fdb4c3696d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..f05382f54c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-of.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..d9d673b891 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {if (false) ; else function f() { }break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..b4ebb46742 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-switch.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..76ed8c4ffb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js @@ -0,0 +1,62 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js new file mode 100644 index 0000000000..1eb39d30fa --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;if (false) ; else function f() { }after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js new file mode 100644 index 0000000000..e4db767e06 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-if-stmt-else-decl.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'if (false) ; else function f() { return "declaration"; }after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js new file mode 100644 index 0000000000..54cd879734 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' + + '}\ + varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..6acc926d73 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..706f35141c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-block-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }switch (1) {' + + ' case 1:' + + ' function f() { return "second declaration"; }' + + '}\ + updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..f4ecb2da58 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-no-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;switch (1) {' + + ' case 1:' + + ' function f() { return "inner declaration"; }' + + '}\ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..0be338236c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "inner declaration"; }' + + '}\ + after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..eeac4cb415 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js new file mode 100644 index 0000000000..3d1c625b90 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-existing-var-update.js @@ -0,0 +1,41 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "function declaration"; }' + + '}\ + after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js new file mode 100644 index 0000000000..a07ad2142d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js new file mode 100644 index 0000000000..6e53d608e3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension observed when there is a formal parameter with the same name (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js new file mode 100644 index 0000000000..c62040f8fd --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {switch (1) {' + + ' case 1:' + + ' function f() { return 123; }' + + '}\ + }\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..e9a309f9a7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..58648dd301 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..2365574e72 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-of.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..546e26fc83 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..c53167f65f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-switch.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..b0e7deb17f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js new file mode 100644 index 0000000000..740e12f902 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js new file mode 100644 index 0000000000..0a7971f061 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-switch-case.template +/*--- +description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "declaration"; }' + + '}\ + after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js new file mode 100644 index 0000000000..690c57f19e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-block-scoping.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV, varBinding; + +(function() { + eval( + 'switch (1) {' + + ' default:' + + ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' + + '}\ + varBinding = f;\ + f();' + ); +}()); + + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + varBinding(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js new file mode 100644 index 0000000000..d8b42c5dab --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'init = f;\ + \ + {\ + function f() {}\ + }switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js new file mode 100644 index 0000000000..d7dfedaadd --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-block-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-block-fn-update.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var updated; + +(function() { + eval( + '{\ + function f() {\ + return "first declaration";\ + }\ + }switch (1) {' + + ' default:' + + ' function f() { return "second declaration"; }' + + '}\ + updated = f;' + ); +}()); + +assert.sameValue(typeof updated, 'function'); +assert.sameValue(updated(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js new file mode 100644 index 0000000000..2b80cd24e0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-no-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var init; + +(function() { + eval( + 'init = f;switch (1) {' + + ' default:' + + ' function f() { return "inner declaration"; }' + + '}\ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(init(), 'outer declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js new file mode 100644 index 0000000000..2dfcdf7668 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-fn-update.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "inner declaration"; }' + + '}\ + after = f;\ + \ + function f() {\ + return "outer declaration";\ + }' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'inner declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js new file mode 100644 index 0000000000..13919adb04 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-no-init.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ +var init; + +(function() { + eval( + 'var f = 123;\ + init = f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, 123); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js new file mode 100644 index 0000000000..37425a531a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-existing-var-update.js @@ -0,0 +1,41 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-existing-var-update.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "function declaration"; }' + + '}\ + after = f;\ + \ + var f = 123;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'function declaration'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js new file mode 100644 index 0000000000..440224c9c2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-init.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + i. If varEnvRec is a global Environment Record, then + [...] + ii. Else, + i. Let bindingExists be varEnvRec.HasBinding(F). + ii. If bindingExists is false, then + i. Perform ! varEnvRec.CreateMutableBinding(F, true). + ii. Perform ! varEnvRec.InitializeBinding(F, undefined). + [...] +---*/ +var init, changed; + +(function() { + eval( + 'init = f;\ + f = 123;\ + changed = f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' + ); +}()); + +assert.sameValue(init, undefined, 'binding is initialized to `undefined`'); +assert.sameValue(changed, 123, 'binding is mutable'); +assert.throws(ReferenceError, function() { + f; +}, 'global binding is not created'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js new file mode 100644 index 0000000000..a12601f4be --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-param.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension observed when there is a formal parameter with the same name (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function(f) { + eval( + 'init = f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + after = f;' + ); +}(123)); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue( + typeof after, 'function', 'value is updated following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js new file mode 100644 index 0000000000..c9e3e361f5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-no-skip-try.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {switch (1) {' + + ' default:' + + ' function f() { return 123; }' + + '}\ + }\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js new file mode 100644 index 0000000000..190319b3e2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-block.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + {\ + let f = 123;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js new file mode 100644 index 0000000000..5bc34c75d2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-in.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f in { key: 0 }) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js new file mode 100644 index 0000000000..5a0b73bfa2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-of.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for-of.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f of [0]) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js new file mode 100644 index 0000000000..2aa2675c82 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-for.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + for (let f; ; ) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + break;\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js new file mode 100644 index 0000000000..a7b71f4fb3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-switch.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-switch.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + switch (0) {\ + default:\ + let f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js new file mode 100644 index 0000000000..ab2e0d09cb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js @@ -0,0 +1,57 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err-try.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +(function() { + eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' + ); +}()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js new file mode 100644 index 0000000000..bb4a289e0e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-skip-early-err.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +var init, after; + +(function() { + eval( + 'let f = 123;\ + init = f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + after = f;' + ); +}()); + +assert.sameValue(init, 123, 'binding is not initialized to `undefined`'); +assert.sameValue(after, 123, 'value is not updated following evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js new file mode 100644 index 0000000000..1767b8b56b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-func-update.case +// - src/annex-b-fns/eval-func/direct-switch-dflt.template +/*--- +description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +var after; + +(function() { + eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "declaration"; }' + + '}\ + after = f;' + ); +}()); + +assert.sameValue(typeof after, 'function'); +assert.sameValue(after(), 'declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js new file mode 100644 index 0000000000..5840488e11 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: A block-scoped binding is created (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + '{ function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } }' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..cd457a9b6b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,24 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Does not re-initialize binding created by similar forms (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }{ function f() { } }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..01172ae73f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-block-fn-update.js @@ -0,0 +1,36 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable-scoped binding is updated (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + '{ function f() { return "second declaration"; } }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..f30e873510 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-no-init.js @@ -0,0 +1,22 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Existing variable binding is not modified (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");{ function f() { return "inner declaration"; } }function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..9ebdbdadf4 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-fn-update.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + '{ function f() { return "inner declaration"; } }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js new file mode 100644 index 0000000000..91ea8b26b8 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-init.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable binding is left in place by legacy function hoisting (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });{ function f() { } }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js new file mode 100644 index 0000000000..33fdb13721 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + '{ function f() { return "function declaration"; } }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..7204c5ff5b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });{ function f() { } }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..b653df30c5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-no-init.js @@ -0,0 +1,21 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Existing variable binding is not modified (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);{ function f() { } }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js new file mode 100644 index 0000000000..07ea9c9ddb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-var-update.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable-scoped binding is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + '{ function f() { return "function declaration"; } }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js new file mode 100644 index 0000000000..c623519d81 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });{ function f() { } }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js new file mode 100644 index 0000000000..144a50ff8d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {{ function f() { return 123; } }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..442effecd9 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js @@ -0,0 +1,40 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;{ function f() { } }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..ffb8f01ee1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {{ function f() { } }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..e12f3f9cdf --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-of.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {{ function f() { } }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..3bdcbf5e55 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for.js @@ -0,0 +1,40 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {{ function f() { } }break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..13b0656643 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-switch.js @@ -0,0 +1,41 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;{ function f() { } }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..0b3c4f3e34 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js @@ -0,0 +1,51 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {{ function f() { } }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js new file mode 100644 index 0000000000..072f3cefa1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js @@ -0,0 +1,23 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");{ function f() { } }assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js new file mode 100644 index 0000000000..fce91ea18f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js @@ -0,0 +1,29 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-block.template +/*--- +description: Variable binding value is updated following evaluation (Block statement in eval code containing a function declaration) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + '{ function f() { return "declaration"; } }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js new file mode 100644 index 0000000000..bd1871bea6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else function _f() {}' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..c55406f3e6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }if (true) function f() { } else function _f() {}' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..00bb3ebbe6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-block-fn-update.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'if (true) function f() { return "second declaration"; } else function _f() {}' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..6dbc46727a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-no-init.js @@ -0,0 +1,31 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else function _f() {}function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..3cf73b92c6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "inner declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js new file mode 100644 index 0000000000..9b570eafc1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });if (true) function f() { } else function _f() {}' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js new file mode 100644 index 0000000000..8da6813afe --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'if (true) function f() { return "function declaration"; } else function _f() {}' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..d307ae71ca --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });if (true) function f() { } else function _f() {}' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..1de4d888a7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);if (true) function f() { } else function _f() {}' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js new file mode 100644 index 0000000000..43575b820b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-var-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "function declaration"; } else function _f() {}' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js new file mode 100644 index 0000000000..b1f5d3e40c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });if (true) function f() { } else function _f() {}' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js new file mode 100644 index 0000000000..2ad6e35513 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; } else function _f() {}}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..0f8badd847 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;if (true) function f() { } else function _f() {}}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..fd73cacbf6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {if (true) function f() { } else function _f() {}}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..6fd5517f51 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-of.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {if (true) function f() { } else function _f() {}}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..4123b4d0de --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {if (true) function f() { } else function _f() {}break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..b85956ea8e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-switch.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;if (true) function f() { } else function _f() {}}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..52d2fa1a47 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js @@ -0,0 +1,60 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { } else function _f() {}}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js new file mode 100644 index 0000000000..362e2c12bb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js @@ -0,0 +1,32 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else function _f() {}assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js new file mode 100644 index 0000000000..ba396ac827 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-a.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "declaration"; } else function _f() {}assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js new file mode 100644 index 0000000000..c7660f4522 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'if (false) function _f() {} else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..1cb1987281 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }if (false) function _f() {} else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..d1f08ff72b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-block-fn-update.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'if (false) function _f() {} else function f() { return "second declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..45ab2ac914 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-no-init.js @@ -0,0 +1,31 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");if (false) function _f() {} else function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..a086f12d7c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) function _f() {} else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js new file mode 100644 index 0000000000..2ed1e34431 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });if (false) function _f() {} else function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js new file mode 100644 index 0000000000..c31ccf055e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'if (false) function _f() {} else function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..305db7f8c5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });if (false) function _f() {} else function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..36263be7c4 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);if (false) function _f() {} else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js new file mode 100644 index 0000000000..68bdffca61 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-var-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) function _f() {} else function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js new file mode 100644 index 0000000000..9f160ecd44 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });if (false) function _f() {} else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js new file mode 100644 index 0000000000..fe995f4bd4 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (false) function _f() {} else function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..d4eb7c3028 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;if (false) function _f() {} else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..6728a080a0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {if (false) function _f() {} else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..03a0fb211d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-of.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {if (false) function _f() {} else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..fe1e9f54eb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {if (false) function _f() {} else function f() { }break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..bd50eeed58 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-switch.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;if (false) function _f() {} else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..cb5d5a7c85 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js @@ -0,0 +1,60 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (false) function _f() {} else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js new file mode 100644 index 0000000000..eaca19d8f0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js @@ -0,0 +1,32 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) function _f() {} else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js new file mode 100644 index 0000000000..c8a0558349 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-decl-b.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in both statement positions in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) function _f() {} else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js new file mode 100644 index 0000000000..84ac92489c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; } else ;' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..531a25f086 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }if (true) function f() { } else ;' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..ee47fed2e6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-block-fn-update.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'if (true) function f() { return "second declaration"; } else ;' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..5cc2909036 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-no-init.js @@ -0,0 +1,31 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; } else ;function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..25a8cd02b6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "inner declaration"; } else ;assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js new file mode 100644 index 0000000000..3804c3c5d7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });if (true) function f() { } else ;' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js new file mode 100644 index 0000000000..aef8081328 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-global-update.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'if (true) function f() { return "function declaration"; } else ;' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..f76ac278be --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });if (true) function f() { } else ;' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..4efa8e99cf --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);if (true) function f() { } else ;' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js new file mode 100644 index 0000000000..343d40399c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-existing-var-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "function declaration"; } else ;' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js new file mode 100644 index 0000000000..5202231f75 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });if (true) function f() { } else ;' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js new file mode 100644 index 0000000000..e46c03ff9a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; } else ;}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..e42f9c995c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;if (true) function f() { } else ;}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..03ee9404d5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {if (true) function f() { } else ;}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..0c56312a50 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-of.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {if (true) function f() { } else ;}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..04b01bfaa7 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {if (true) function f() { } else ;break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..c130d23ece --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-switch.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;if (true) function f() { } else ;}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..5787a86a77 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js @@ -0,0 +1,60 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { } else ;}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js new file mode 100644 index 0000000000..0e5e13743d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js @@ -0,0 +1,32 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { } else ;assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js new file mode 100644 index 0000000000..22d6905e4c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-else-stmt.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in the first statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "declaration"; } else ;assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js new file mode 100644 index 0000000000..c2dec25011 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: A block-scoped binding is created (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'if (true) function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..46b3fb179e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }if (true) function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..46a6dc9861 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-block-fn-update.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'if (true) function f() { return "second declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..c5e44f12e3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-no-init.js @@ -0,0 +1,31 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Existing variable binding is not modified (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");if (true) function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..f4cf01ce8a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js new file mode 100644 index 0000000000..70eec47a74 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable binding is left in place by legacy function hoisting (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });if (true) function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js new file mode 100644 index 0000000000..8e8922ac59 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-global-update.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'if (true) function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..36319fc697 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });if (true) function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..9c03509911 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Existing variable binding is not modified (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);if (true) function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js new file mode 100644 index 0000000000..001326e03a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-existing-var-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js new file mode 100644 index 0000000000..2c1121e2d6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });if (true) function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js new file mode 100644 index 0000000000..a7b457c08d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (true) function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..d2c9f1e277 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;if (true) function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..daf0b03731 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {if (true) function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..61f4f03e60 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-of.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {if (true) function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..fc006bfe76 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {if (true) function f() { }break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..f532f79ae1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-switch.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;if (true) function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..4eeb4e633b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js @@ -0,0 +1,60 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (true) function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js new file mode 100644 index 0000000000..5ebc6cfc4d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js @@ -0,0 +1,32 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (true) function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js new file mode 100644 index 0000000000..1f396a89a5 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-if-decl-no-else.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement without an else clause in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (true) function f() { return "declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js new file mode 100644 index 0000000000..c8e410fe38 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: A block-scoped binding is created (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'if (false) ; else function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..bd2ff524a0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Does not re-initialize binding created by similar forms (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }if (false) ; else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..da854b53df --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-block-fn-update.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'if (false) ; else function f() { return "second declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..4c434402ca --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-no-init.js @@ -0,0 +1,31 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");if (false) ; else function f() { return "inner declaration"; }function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..1835faf6a1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-fn-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) ; else function f() { return "inner declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js new file mode 100644 index 0000000000..4f04be8aa3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable binding is left in place by legacy function hoisting (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });if (false) ; else function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js new file mode 100644 index 0000000000..297c307fa3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-update.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'if (false) ; else function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..668b112545 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,52 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });if (false) ; else function f() { }' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..1f28a31233 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-no-init.js @@ -0,0 +1,30 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Existing variable binding is not modified (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);if (false) ; else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js new file mode 100644 index 0000000000..cf1f9d8235 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-var-update.js @@ -0,0 +1,42 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable-scoped binding is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) ; else function f() { return "function declaration"; }' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js new file mode 100644 index 0000000000..ed46bb57a1 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });if (false) ; else function f() { }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js new file mode 100644 index 0000000000..4c2d8aa178 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {if (false) ; else function f() { return 123; }}\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..32a5b08edb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;if (false) ; else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..6560a6dc6e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {if (false) ; else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..44ce2beaed --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-of.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {if (false) ; else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..0606b0417a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {if (false) ; else function f() { }break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..523924c4d8 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-switch.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;if (false) ; else function f() { }}' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..081172cc60 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js @@ -0,0 +1,60 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {if (false) ; else function f() { }}\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js new file mode 100644 index 0000000000..55e67d5a1b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js @@ -0,0 +1,32 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");if (false) ; else function f() { }assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js new file mode 100644 index 0000000000..55d7c28fdd --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-if-stmt-else-decl.template +/*--- +description: Variable binding value is updated following evaluation (IfStatement with a declaration in the second statement position in eval code) +esid: sec-functiondeclarations-in-ifstatement-statement-clauses +flags: [generated, noStrict] +info: | + The following rules for IfStatement augment those in 13.6: + + IfStatement[Yield, Return]: + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else Statement[?Yield, ?Return] + if ( Expression[In, ?Yield] ) Statement[?Yield, ?Return] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] else FunctionDeclaration[?Yield] + if ( Expression[In, ?Yield] ) FunctionDeclaration[?Yield] + + + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'if (false) ; else function f() { return "declaration"; }assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js new file mode 100644 index 0000000000..0bf1535d92 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: A block-scoped binding is created (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' + + '}\ + ' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..1a6fbe35d2 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,28 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Does not re-initialize binding created by similar forms (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..26ae63c0bb --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-block-fn-update.js @@ -0,0 +1,40 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "second declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..9e987fa576 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-no-init.js @@ -0,0 +1,26 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");switch (1) {' + + ' case 1:' + + ' function f() { return "inner declaration"; }' + + '}\ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..9162230086 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-fn-update.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "inner declaration"; }' + + '}\ + assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js new file mode 100644 index 0000000000..9786610e2c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable binding is left in place by legacy function hoisting (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js new file mode 100644 index 0000000000..2e399df93c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-global-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "function declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..7e7fcabd67 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..47fa604f5e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-no-init.js @@ -0,0 +1,25 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Existing variable binding is not modified (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js new file mode 100644 index 0000000000..8ee5f582c3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-existing-var-update.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable-scoped binding is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "function declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js new file mode 100644 index 0000000000..229410f0fe --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js new file mode 100644 index 0000000000..1210887549 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {switch (1) {' + + ' case 1:' + + ' function f() { return 123; }' + + '}\ + }\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..02bab370e3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..cae6d7676f --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..d703814eb3 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-of.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..27f6664775 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..253ed73cc6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-switch.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..b2d625c02a --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js new file mode 100644 index 0000000000..8a9c92b466 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js @@ -0,0 +1,27 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' + + ' case 1:' + + ' function f() { }' + + '}\ + assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js new file mode 100644 index 0000000000..198649ed29 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-switch-case.template +/*--- +description: Variable binding value is updated following evaluation (Function declaration in the `case` clause of a `switch` statement in eval code) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' case 1:' + + ' function f() { return "declaration"; }' + + '}\ + assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js new file mode 100644 index 0000000000..ba7a492e64 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js @@ -0,0 +1,50 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-block-scoping.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: A block-scoped binding is created (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + 13.2.14 Runtime Semantics: BlockDeclarationInstantiation + + [...] + 4. For each element d in declarations do + a. For each element dn of the BoundNames of d do + i. If IsConstantDeclaration of d is true, then + [...] + ii. Else, + 2. Perform ! envRec.CreateMutableBinding(dn, false). + + b. If d is a GeneratorDeclaration production or a FunctionDeclaration + production, then + i. Let fn be the sole element of the BoundNames of d. + ii. Let fo be the result of performing InstantiateFunctionObject for + d with argument env. + iii. Perform envRec.InitializeBinding(fn, fo). +---*/ +var initialBV, currentBV; + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { initialBV = f; f = 123; currentBV = f; return "decl"; }' + + '}\ + ' +); + +f(); + +assert.sameValue( + initialBV(), + 'decl', + 'Block-scoped binding value is function object at execution time' +); +assert.sameValue(currentBV, 123, 'Block-scoped binding is mutable'); +assert.sameValue( + f(), + 'decl', + 'Block-scoped binding is independent of outer var-scoped binding' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js new file mode 100644 index 0000000000..f9237012f6 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-no-init.js @@ -0,0 +1,28 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Does not re-initialize binding created by similar forms (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f, undefined);\ + \ + {\ + function f() {}\ + }switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js new file mode 100644 index 0000000000..52ed82190c --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-block-fn-update.js @@ -0,0 +1,40 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-block-fn-update.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ +{ + function f() { + return 'first declaration'; + } +} + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "second declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'second declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js new file mode 100644 index 0000000000..d7b5a0786e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-no-init.js @@ -0,0 +1,26 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'assert.sameValue(f(), "outer declaration");switch (1) {' + + ' default:' + + ' function f() { return "inner declaration"; }' + + '}\ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js new file mode 100644 index 0000000000..780449a32d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-fn-update.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-fn-update.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "inner declaration"; }' + + '}\ + assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "inner declaration");\ + \ + function f() {\ + return "outer declaration";\ + }' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js new file mode 100644 index 0000000000..f0da10714e --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable binding is left in place by legacy function hoisting (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: false\ + }, { restore: true });switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, "f", { + enumerable: true, + writable: true, + configurable: false +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js new file mode 100644 index 0000000000..b2fe4cbaaa --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-global-update.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-global-update.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: function() { return 'Another function'; }, + enumerable: true, + writable: true, + configurable: false +}); + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "function declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js new file mode 100644 index 0000000000..e2ebe8da66 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-non-enumerable-global-init.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-non-enumerable-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable binding is left in place by legacy function hoisting. CreateGlobalVariableBinding leaves the binding as non-enumerable even if it has the chance to change it to be enumerable. (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalVarBinding(F, true). + [...] + +---*/ +Object.defineProperty(fnGlobalObject(), 'f', { + value: 'x', + enumerable: false, + writable: true, + configurable: true +}); + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, "x", "binding is not reinitialized");\ + \ + verifyProperty(global, "f", {\ + enumerable: false,\ + writable: true,\ + configurable: true\ + }, { restore: true });switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' +); + +assert.sameValue(typeof f, "function"); +verifyProperty(global, 'f', { + enumerable: false, + writable: true, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js new file mode 100644 index 0000000000..0d69f2e47b --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-no-init.js @@ -0,0 +1,25 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-no-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Existing variable binding is not modified (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + a. If declaredFunctionOrVarNames does not contain F, then + [...] +---*/ + +eval( + 'var f = 123;\ + assert.sameValue(f, 123);switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js new file mode 100644 index 0000000000..09da0ec602 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-existing-var-update.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-existing-var-update.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable-scoped binding is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "function declaration"; }' + + '}\ + ' +); + +assert.sameValue(typeof f, 'function'); +assert.sameValue(f(), 'function declaration'); + +var f = 123; + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js new file mode 100644 index 0000000000..5028ad5b23 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-init.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable binding is initialized to `undefined` in outer scope (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +includes: [fnGlobalObject.js, propertyHelper.js] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + i. If varEnvRec is a global Environment Record, then + i. Perform ? varEnvRec.CreateGlobalFunctionBinding(F, undefined, true). + [...] + +---*/ + +eval( + 'var global = fnGlobalObject();\ + assert.sameValue(f, undefined, "binding is initialized to `undefined`");\ + \ + verifyProperty(global, "f", {\ + enumerable: true,\ + writable: true,\ + configurable: true\ + });switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + ' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js new file mode 100644 index 0000000000..398cbc09d0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-no-skip-try.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension is observed when creation of variable binding would not produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.sameValue(\ + f, undefined, "Initialized binding created prior to evaluation"\ + );\ + \ + try {\ + throw null;\ + } catch (f) {switch (1) {' + + ' default:' + + ' function f() { return 123; }' + + '}\ + }\ + \ + assert.sameValue(\ + typeof f,\ + "function",\ + "binding value is updated following evaluation"\ + );\ + assert.sameValue(f(), 123);' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js new file mode 100644 index 0000000000..95bec64703 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-block.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Block statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + '{\ + let f = 123;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js new file mode 100644 index 0000000000..34731cb943 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-in.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f in { key: 0 }) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js new file mode 100644 index 0000000000..7a87bd93dc --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-of.js @@ -0,0 +1,43 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for-of.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for-of statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f of [0]) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js new file mode 100644 index 0000000000..cb4f0ab896 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for.js @@ -0,0 +1,44 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-for.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (for statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'for (let f; ; ) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + break;\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js new file mode 100644 index 0000000000..be6f13629d --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-switch.js @@ -0,0 +1,45 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-switch.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (switch statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created prior to evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created prior to evaluation' +); + +eval( + 'switch (0) {\ + default:\ + let f;switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }' +); + +assert.throws(ReferenceError, function() { + f; +}, 'An initialized binding is not created following evaluation'); +assert.sameValue( + typeof f, + 'undefined', + 'An uninitialized binding is not created following evaluation' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js new file mode 100644 index 0000000000..3cdad6b1d9 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js @@ -0,0 +1,55 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err-try.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension is not observed when creation of variable binding would produce an early error (try statement) (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] + + B.3.5 VariableStatements in Catch Blocks + + [...] + - It is a Syntax Error if any element of the BoundNames of CatchParameter + also occurs in the VarDeclaredNames of Block unless CatchParameter is + CatchParameter:BindingIdentifier and that element is only bound by a + VariableStatement, the VariableDeclarationList of a for statement, or the + ForBinding of a for-in statement. +---*/ + +eval( + 'assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created prior to evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created prior to evaluation"\ + );\ + \ + try {\ + throw {};\ + } catch ({ f }) {switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + }\ + \ + assert.throws(ReferenceError, function() {\ + f;\ + }, "An initialized binding is not created following evaluation");\ + assert.sameValue(\ + typeof f,\ + "undefined",\ + "An uninitialized binding is not created following evaluation"\ + );' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js new file mode 100644 index 0000000000..896ffef4d0 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js @@ -0,0 +1,27 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-skip-early-err.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Extension not observed when creation of variable binding would produce an early error (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + ii. If replacing the FunctionDeclaration f with a VariableStatement that + has F as a BindingIdentifier would not produce any Early Errors for + body, then + [...] +---*/ + +eval( + 'let f = 123;\ + assert.sameValue(f, 123, "binding is not initialized to `undefined`");switch (1) {' + + ' default:' + + ' function f() { }' + + '}\ + assert.sameValue(f, 123, "value is not updated following evaluation");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js new file mode 100644 index 0000000000..ea66a62173 --- /dev/null +++ b/js/src/tests/test262/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js @@ -0,0 +1,33 @@ +// This file was procedurally generated from the following sources: +// - src/annex-b-fns/eval-global-update.case +// - src/annex-b-fns/eval-global/direct-switch-dflt.template +/*--- +description: Variable binding value is updated following evaluation (Funtion declaration in the `default` clause of a `switch` statement in eval code in the global scope) +esid: sec-web-compat-evaldeclarationinstantiation +flags: [generated, noStrict] +info: | + B.3.3.3 Changes to EvalDeclarationInstantiation + + [...] + b. When the FunctionDeclaration f is evaluated, perform the following steps + in place of the FunctionDeclaration Evaluation algorithm provided in + 14.1.21: + i. Let genv be the running execution context's VariableEnvironment. + ii. Let genvRec be genv's EnvironmentRecord. + iii. Let benv be the running execution context's LexicalEnvironment. + iv. Let benvRec be benv's EnvironmentRecord. + v. Let fobj be ! benvRec.GetBindingValue(F, false). + vi. Perform ? genvRec.SetMutableBinding(F, fobj, false). + vii. Return NormalCompletion(empty). +---*/ + +eval( + 'switch (1) {' + + ' default:' + + ' function f() { return "declaration"; }' + + '}\ + assert.sameValue(typeof f, "function");\ + assert.sameValue(f(), "declaration");' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/annexB/language/eval-code/direct/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 |