From 2b973de4e95f381531e0f4dd3f54dcde80146eda Mon Sep 17 00:00:00 2001 From: Caio Lima Date: Mon, 19 Aug 2019 21:13:47 -0300 Subject: [PATCH] Adding multiple class evaluation cases for private static accessors --- ...ltiple-evaluations-of-class-direct-eval.js | 54 ++++++++++++++++ ...iple-evaluations-of-class-eval-indirect.js | 54 ++++++++++++++++ ...r-multiple-evaluations-of-class-factory.js | 49 +++++++++++++++ ...iple-evaluations-of-class-function-ctor.js | 54 ++++++++++++++++ ...ter-multiple-evaluations-of-class-realm.js | 59 ++++++++++++++++++ ...ltiple-evaluations-of-class-direct-eval.js | 56 +++++++++++++++++ ...iple-evaluations-of-class-eval-indirect.js | 56 +++++++++++++++++ ...r-multiple-evaluations-of-class-factory.js | 51 ++++++++++++++++ ...iple-evaluations-of-class-function-ctor.js | 56 +++++++++++++++++ ...ter-multiple-evaluations-of-class-realm.js | 61 +++++++++++++++++++ 10 files changed, 550 insertions(+) create mode 100644 test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-direct-eval.js create mode 100644 test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-eval-indirect.js create mode 100644 test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-factory.js create mode 100644 test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-function-ctor.js create mode 100644 test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-realm.js create mode 100644 test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-direct-eval.js create mode 100644 test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-eval-indirect.js create mode 100644 test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-factory.js create mode 100644 test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-function-ctor.js create mode 100644 test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-realm.js diff --git a/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-direct-eval.js b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-direct-eval.js new file mode 100644 index 0000000000..ed52614de2 --- /dev/null +++ b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-direct-eval.js @@ -0,0 +1,54 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static getter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static get #m() { + return 'Test262'; + }; + + static access() { + return this.#m; + } +} +)`; + +let evalClass = function () { + return eval(classStringExpression); +}; + +let C1 = evalClass(); +let C2 = evalClass(); + +assert.sameValue(C1.access(), 'Test262'); +assert.sameValue(C2.access(), 'Test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static getter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static getter'); diff --git a/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-eval-indirect.js b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-eval-indirect.js new file mode 100644 index 0000000000..18b7a69e52 --- /dev/null +++ b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-eval-indirect.js @@ -0,0 +1,54 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static getter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static get #m() { + return 'test262'; + }; + + static access() { + return this.#m; + } +} +)`; + +let evalClass = function (_eval) { + return _eval(classStringExpression); +}; + +let C1 = evalClass(eval); +let C2 = evalClass(eval); + +assert.sameValue(C1.access(), 'test262'); +assert.sameValue(C2.access(), 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static getter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static getter'); diff --git a/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-factory.js b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-factory.js new file mode 100644 index 0000000000..17634f62e6 --- /dev/null +++ b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-factory.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static getter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +---*/ + +let createClass = function () { + return class { + static get #m() { + return 'test262'; + }; + + static access() { + return this.#m; + } + } +}; + +let C1 = createClass(); +let C2 = createClass(); + +assert.sameValue(C1.access(), 'test262'); +assert.sameValue(C2.access(), 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static getter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static getter'); diff --git a/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-function-ctor.js b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-function-ctor.js new file mode 100644 index 0000000000..f84f8dd018 --- /dev/null +++ b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-function-ctor.js @@ -0,0 +1,54 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static getter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +---*/ + +let classStringExpression = ` +return class { + static get #m() { + return 'test262'; + }; + + static access() { + return this.#m; + } +} +`; + +let createClass = function () { + let classFactoryFunction = new Function(classStringExpression); + return classFactoryFunction(); +}; + +let C1 = createClass(); +let C2 = createClass(); + +assert.sameValue(C1.access(), 'test262'); +assert.sameValue(C2.access(), 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static getter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static getter'); diff --git a/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-realm.js b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-realm.js new file mode 100644 index 0000000000..79b0920001 --- /dev/null +++ b/test/language/expressions/class/private-static-getter-multiple-evaluations-of-class-realm.js @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static getter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let global1 = $262.createRealm().global; +let global2 = $262.createRealm().global; +let eval1 = global1.eval; +let eval2 = global2.eval; + +let classStringExpression = `( +class { + static get #m() { + return 'test262'; + }; + + static access() { + return this.#m; + } +} +)`; + +let evalClass = function (_eval) { + return _eval(classStringExpression); +}; + +let C1 = evalClass(eval1); +let C2 = evalClass(eval2); + +assert.sameValue(C1.access(), 'test262'); +assert.sameValue(C2.access(), 'test262'); + +assert.throws(global1.TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static getter'); + +assert.throws(global2.TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static getter'); diff --git a/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-direct-eval.js b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-direct-eval.js new file mode 100644 index 0000000000..14e6cae4fc --- /dev/null +++ b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-direct-eval.js @@ -0,0 +1,56 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static setter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static set #m(v) { + this._v = v; + } + + static access() { + this.#m = 'test262'; + } +} +)`; + +let evalClass = function () { + return eval(classStringExpression); +}; + +let C1 = evalClass(); +let C2 = evalClass(); + +C1.access(); +assert.sameValue(C1._v, 'test262'); +C2.access(); +assert.sameValue(C2._v, 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static setter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static setter'); diff --git a/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-eval-indirect.js b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-eval-indirect.js new file mode 100644 index 0000000000..fffef195a8 --- /dev/null +++ b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-eval-indirect.js @@ -0,0 +1,56 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static setter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static set #m(v) { + this._v = v; + }; + + static access() { + this.#m = 'test262'; + } +} +)`; + +let evalClass = function (_eval) { + return _eval(classStringExpression); +}; + +let C1 = evalClass(eval); +let C2 = evalClass(eval); + +C1.access(); +assert.sameValue(C1._v, 'test262'); +C2.access(); +assert.sameValue(C2._v, 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static setter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static setter'); diff --git a/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-factory.js b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-factory.js new file mode 100644 index 0000000000..67739e68f9 --- /dev/null +++ b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-factory.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static setter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +---*/ + +let createClass = function () { + return class { + static set #m(v) { + this._v = v; + }; + + static access() { + this.#m = 'test262'; + } + } +}; + +let C1 = createClass(); +let C2 = createClass(); + +C1.access(); +assert.sameValue(C1._v, 'test262'); +C2.access(); +assert.sameValue(C2._v, 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static setter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static setter'); diff --git a/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-function-ctor.js b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-function-ctor.js new file mode 100644 index 0000000000..74a477231b --- /dev/null +++ b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-function-ctor.js @@ -0,0 +1,56 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static setter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +---*/ + +let classStringExpression = ` +return class { + static set #m(v) { + this._v = v; + } + + static access() { + this.#m = 'test262'; + } +} +`; + +let createClass = function () { + let classFactoryFunction = new Function(classStringExpression); + return classFactoryFunction(); +}; + +let C1 = createClass(); +let C2 = createClass(); + +C1.access(); +assert.sameValue(C1._v, 'test262'); +C2.access(); +assert.sameValue(C2._v, 'test262'); + +assert.throws(TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static setter'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static setter'); diff --git a/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-realm.js b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-realm.js new file mode 100644 index 0000000000..acaf7cfc5c --- /dev/null +++ b/test/language/expressions/class/private-static-setter-multiple-evaluations-of-class-realm.js @@ -0,0 +1,61 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Every new evaluation of a class creates a different Private Name (private static setter) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassTail : ClassHeritage { ClassBody } + ... + 19. Let F be constructorInfo.[[Closure]]. + 20. If ClassHeritage_opt is present and protoParent is not null, then set F.[[ConstructorKind]] to "derived". + 21. Perform MakeConstructor(F, false, proto). + 22. Perform MakeClassConstructor(F). + ... + 33. If PrivateBoundIdentifiers of ClassBody contains a Private Name P such that P's [[Kind]] field is either "method" or "accessor" and P's [[Brand]] is F, + a. PrivateBrandAdd(F, F). + ... + + PrivateBrandCheck(O, P) + 1. If O.[[PrivateBrands]] does not contain an entry e such that SameValue(e, P.[[Brand]]) is true, + a. Throw a TypeError exception. +features: [class, class-static-methods-private] +flags: [noStrict] +---*/ + +let global1 = $262.createRealm().global; +let global2 = $262.createRealm().global; +let eval1 = global1.eval; +let eval2 = global2.eval; + +let classStringExpression = `( +class { + static set #m(v) { + this._v = v; + } + + static access() { + this.#m = 'test262'; + } +} +)`; + +let evalClass = function (_eval) { + return _eval(classStringExpression); +}; + +let C1 = evalClass(eval1); +let C2 = evalClass(eval2); + +C1.access(); +assert.sameValue(C1._v, 'test262'); +C2.access(); +assert.sameValue(C2._v, 'test262'); + +assert.throws(global1.TypeError, function() { + C1.access.call(C2); +}, 'invalid access of C1 private static setter'); + +assert.throws(global2.TypeError, function() { + C2.access.call(C1); +}, 'invalid access of C2 private static setter');