From f947f93887ce56f3a7df07c2847c3211d249ade7 Mon Sep 17 00:00:00 2001 From: Caio Lima Date: Wed, 14 Aug 2019 14:32:11 -0300 Subject: [PATCH] Private static members with multiple evaluation of class (#2291) --- ...ltiple-evaluations-of-class-direct-eval.js | 68 +++++++++++++++++ ...iple-evaluations-of-class-eval-indirect.js | 68 +++++++++++++++++ ...d-multiple-evaluations-of-class-factory.js | 63 ++++++++++++++++ ...iple-evaluations-of-class-function-ctor.js | 68 +++++++++++++++++ ...eld-multiple-evaluations-of-class-realm.js | 73 +++++++++++++++++++ ...ltiple-evaluations-of-class-direct-eval.js | 52 +++++++++++++ ...iple-evaluations-of-class-eval-indirect.js | 52 +++++++++++++ ...k-multiple-evaluations-of-class-factory.js | 47 ++++++++++++ ...iple-evaluations-of-class-function-ctor.js | 52 +++++++++++++ ...eck-multiple-evaluations-of-class-realm.js | 57 +++++++++++++++ 10 files changed, 600 insertions(+) create mode 100644 test/language/expressions/class/private-static-field-multiple-evaluations-of-class-direct-eval.js create mode 100644 test/language/expressions/class/private-static-field-multiple-evaluations-of-class-eval-indirect.js create mode 100644 test/language/expressions/class/private-static-field-multiple-evaluations-of-class-factory.js create mode 100644 test/language/expressions/class/private-static-field-multiple-evaluations-of-class-function-ctor.js create mode 100644 test/language/expressions/class/private-static-field-multiple-evaluations-of-class-realm.js create mode 100644 test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-direct-eval.js create mode 100644 test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-eval-indirect.js create mode 100644 test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-factory.js create mode 100644 test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-function-ctor.js create mode 100644 test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-realm.js diff --git a/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-direct-eval.js b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-direct-eval.js new file mode 100644 index 0000000000..6785c6320e --- /dev/null +++ b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-direct-eval.js @@ -0,0 +1,68 @@ +// 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 field) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassElementName : PrivateIdentifier + 1. Let privateIdentifier be StringValue of PrivateIdentifier. + 2. Let privateName be NewPrivateName(privateIdentifier). + 3. Let scope be the running execution context's PrivateEnvironment. + 4. Let scopeEnvRec be scope's EnvironmentRecord. + 5. Perform ! scopeEnvRec.InitializeBinding(privateIdentifier, privateName). + 6. Return privateName. + + ClassTail : ClassHeritage { ClassBody } + ... + 27. Let staticFields be a new empty List. + 28. For each ClassElement e in order from elements, + a. If IsStatic of e is false, then + ... + b. Else, + i. Let field be the result of performing PropertyDefinitionEvaluation for m ClassElementEvaluation for e with arguments F and false. + c. If field is an abrupt completion, then + ... + d. If field is not empty, + i. If IsStatic of e is false, append field to instanceFields. + ii. Otherwise, append field to staticFields. + ... + 34. For each item fieldRecord in order from staticFields, + a. Perform ? DefineField(F, field). + ... + + DefineField(receiver, fieldRecord) + ... + 8. If fieldName is a Private Name, + a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue). +features: [class, class-static-fields-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static #m = '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 field'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static field'); diff --git a/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-eval-indirect.js b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-eval-indirect.js new file mode 100644 index 0000000000..a694d603e6 --- /dev/null +++ b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-eval-indirect.js @@ -0,0 +1,68 @@ +// 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 field) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassElementName : PrivateIdentifier + 1. Let privateIdentifier be StringValue of PrivateIdentifier. + 2. Let privateName be NewPrivateName(privateIdentifier). + 3. Let scope be the running execution context's PrivateEnvironment. + 4. Let scopeEnvRec be scope's EnvironmentRecord. + 5. Perform ! scopeEnvRec.InitializeBinding(privateIdentifier, privateName). + 6. Return privateName. + + ClassTail : ClassHeritage { ClassBody } + ... + 27. Let staticFields be a new empty List. + 28. For each ClassElement e in order from elements, + a. If IsStatic of e is false, then + ... + b. Else, + i. Let field be the result of performing PropertyDefinitionEvaluation for m ClassElementEvaluation for e with arguments F and false. + c. If field is an abrupt completion, then + ... + d. If field is not empty, + i. If IsStatic of e is false, append field to instanceFields. + ii. Otherwise, append field to staticFields. + ... + 34. For each item fieldRecord in order from staticFields, + a. Perform ? DefineField(F, field). + ... + + DefineField(receiver, fieldRecord) + ... + 8. If fieldName is a Private Name, + a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue). +features: [class, class-static-fields-private] +flags: [noStrict] +---*/ + +let classStringExpression = `( +class { + static #m = '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 field'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static field'); diff --git a/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-factory.js b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-factory.js new file mode 100644 index 0000000000..e83d259e4c --- /dev/null +++ b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-factory.js @@ -0,0 +1,63 @@ +// 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 field) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassElementName : PrivateIdentifier + 1. Let privateIdentifier be StringValue of PrivateIdentifier. + 2. Let privateName be NewPrivateName(privateIdentifier). + 3. Let scope be the running execution context's PrivateEnvironment. + 4. Let scopeEnvRec be scope's EnvironmentRecord. + 5. Perform ! scopeEnvRec.InitializeBinding(privateIdentifier, privateName). + 6. Return privateName. + + ClassTail : ClassHeritage { ClassBody } + ... + 27. Let staticFields be a new empty List. + 28. For each ClassElement e in order from elements, + a. If IsStatic of e is false, then + ... + b. Else, + i. Let field be the result of performing PropertyDefinitionEvaluation for m ClassElementEvaluation for e with arguments F and false. + c. If field is an abrupt completion, then + ... + d. If field is not empty, + i. If IsStatic of e is false, append field to instanceFields. + ii. Otherwise, append field to staticFields. + ... + 34. For each item fieldRecord in order from staticFields, + a. Perform ? DefineField(F, field). + ... + + DefineField(receiver, fieldRecord) + ... + 8. If fieldName is a Private Name, + a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue). +features: [class, class-static-fields-private] +---*/ + +let createClass = function () { + return class { + static #m = '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 field'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static field'); diff --git a/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-function-ctor.js b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-function-ctor.js new file mode 100644 index 0000000000..423e27ad5f --- /dev/null +++ b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-function-ctor.js @@ -0,0 +1,68 @@ +// 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 field) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassElementName : PrivateIdentifier + 1. Let privateIdentifier be StringValue of PrivateIdentifier. + 2. Let privateName be NewPrivateName(privateIdentifier). + 3. Let scope be the running execution context's PrivateEnvironment. + 4. Let scopeEnvRec be scope's EnvironmentRecord. + 5. Perform ! scopeEnvRec.InitializeBinding(privateIdentifier, privateName). + 6. Return privateName. + + ClassTail : ClassHeritage { ClassBody } + ... + 27. Let staticFields be a new empty List. + 28. For each ClassElement e in order from elements, + a. If IsStatic of e is false, then + ... + b. Else, + i. Let field be the result of performing PropertyDefinitionEvaluation for m ClassElementEvaluation for e with arguments F and false. + c. If field is an abrupt completion, then + ... + d. If field is not empty, + i. If IsStatic of e is false, append field to instanceFields. + ii. Otherwise, append field to staticFields. + ... + 34. For each item fieldRecord in order from staticFields, + a. Perform ? DefineField(F, field). + ... + + DefineField(receiver, fieldRecord) + ... + 8. If fieldName is a Private Name, + a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue). +features: [class, class-static-fields-private] +---*/ + +let classStringExpression = ` +return class { + static #m = '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 field'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static field'); diff --git a/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-realm.js b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-realm.js new file mode 100644 index 0000000000..0c12f51bc8 --- /dev/null +++ b/test/language/expressions/class/private-static-field-multiple-evaluations-of-class-realm.js @@ -0,0 +1,73 @@ +// 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 field) +esid: sec-runtime-semantics-evaluate-name +info: | + ClassElementName : PrivateIdentifier + 1. Let privateIdentifier be StringValue of PrivateIdentifier. + 2. Let privateName be NewPrivateName(privateIdentifier). + 3. Let scope be the running execution context's PrivateEnvironment. + 4. Let scopeEnvRec be scope's EnvironmentRecord. + 5. Perform ! scopeEnvRec.InitializeBinding(privateIdentifier, privateName). + 6. Return privateName. + + ClassTail : ClassHeritage { ClassBody } + ... + 27. Let staticFields be a new empty List. + 28. For each ClassElement e in order from elements, + a. If IsStatic of e is false, then + ... + b. Else, + i. Let field be the result of performing PropertyDefinitionEvaluation for m ClassElementEvaluation for e with arguments F and false. + c. If field is an abrupt completion, then + ... + d. If field is not empty, + i. If IsStatic of e is false, append field to instanceFields. + ii. Otherwise, append field to staticFields. + ... + 34. For each item fieldRecord in order from staticFields, + a. Perform ? DefineField(F, field). + ... + + DefineField(receiver, fieldRecord) + ... + 8. If fieldName is a Private Name, + a. Perform ? PrivateFieldAdd(fieldName, receiver, initValue). +features: [class, class-static-fields-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 #m = '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 field'); + +assert.throws(global2.TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static field'); diff --git a/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-direct-eval.js b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-direct-eval.js new file mode 100644 index 0000000000..de49f117a1 --- /dev/null +++ b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-direct-eval.js @@ -0,0 +1,52 @@ +// 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 brand (private static methods) +esid: sec-privatefieldget +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 #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 method'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static method'); diff --git a/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-eval-indirect.js b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-eval-indirect.js new file mode 100644 index 0000000000..0ddfcf9478 --- /dev/null +++ b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-eval-indirect.js @@ -0,0 +1,52 @@ +// 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 brand (private static methods) +esid: sec-privatefieldget +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 #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 method'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static method'); diff --git a/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-factory.js b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-factory.js new file mode 100644 index 0000000000..093924fe5c --- /dev/null +++ b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-factory.js @@ -0,0 +1,47 @@ +// 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 brand (private static methods) +esid: sec-privatefieldget +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 #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 method'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static method'); diff --git a/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-function-ctor.js b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-function-ctor.js new file mode 100644 index 0000000000..913a2568dc --- /dev/null +++ b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-function-ctor.js @@ -0,0 +1,52 @@ +// 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 brand (private static methods) +esid: sec-privatefieldget +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 #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 method'); + +assert.throws(TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static method'); diff --git a/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-realm.js b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-realm.js new file mode 100644 index 0000000000..3ada7fe34a --- /dev/null +++ b/test/language/expressions/class/private-static-method-brand-check-multiple-evaluations-of-class-realm.js @@ -0,0 +1,57 @@ +// 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 brand (private static methods) +esid: sec-privatefieldget +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 #m() { return 'test262'; } + + access() { + return this.#m(); + } +} +)`; + +let createClass = function (_eval) { + return _eval(classStringExpression); +}; + +let C1 = createClass(eval1); +let C2 = createClass(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 method'); + +assert.throws(global2.TypeError, function() { + C2.access.call(C1); +}, 'invalid access of c2 private static method');