diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/debug/private-methods-eval-in-frame.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | js/src/jit-test/tests/debug/private-methods-eval-in-frame.js | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js b/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js new file mode 100644 index 0000000000..5122cfa56b --- /dev/null +++ b/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js @@ -0,0 +1,218 @@ +load(libdir + 'evalInFrame.js'); + +class B { + #priv() { + return 12; + } + + #privF = () => { return 12; } + + callPriv() { + return this.#priv(); + } + + callPrivF() { + return this.#privF(); + } + + #val = 'constructed'; + set #x(x) { + this.#val = x + ' haha'; + } + get #x() { + return this.#val; + } + + ef(str) { + return evalInFrame(0, str); + } + + layerEf(str) { + // Nested functions here result in computeEffectiveScope traversing + // more than one environment, necessitating more hops. + function tester(o) { + let a = 10; + function interior(o) { + let b = a; + return evalInFrame(0, str.replace("this", "o")); + }; + return interior(o); + } + return tester(this); + } + + moreLayerEf(str) { + // Nested functions here result in computeEffectiveScope traversing + // more than one environment, necessitating more hops. + function tester(o) { + let a = 0; + function interior(o) { + let b = a; + return (() => { + let k = o; + let replace = str.replace("this", "k"); + print(replace); + return evalInFrame(b, replace); + })(); + }; + return interior(o); + } + return tester(this); + } + + callFunc(f) { + return f(); + } + + static #smethod() { + return 14; + } + + static #unusedmethod() { + return 19; + } + + static get #unusedgetter() { + return 10; + } + + static setter = undefined; + static set #unusedsetter(x) { this.setter = x } + + + static f() { + return this.#smethod(); + } + + static seval(str) { + return eval(str); + } + + static sef(str) { + return evalInFrame(0, str); + } + + + static sLayerEf(str) { + // Nested functions here result in computeEffectiveScope traversing + // more than one environment, necessitating more hops. + function tester(o) { + let a = 10; + function interior(o) { + if (a == 10) { + let b = 10 - a; + return evalInFrame(b, str.replace("this", "o")); + } + }; + return interior(o); + } + return tester(this); + } + + +} + +var b = new B(); + +assertEq(b.ef("this.callPriv()"), 12); +assertEq(b.ef("this.callPrivF()"), 12); + +// Private fields don't need brand checking and should succeed. +assertEq(b.ef("this.#val"), 'constructed') + +// PrivF is a field, not a method, and so isn't brand checked like a method. +assertEq(b.ef(`this.callFunc(() => { return this.#privF() })`), 12); +assertEq(b.ef(`this.#privF()`), 12); + +// Accesors are stored like fields, and so successfully execute, as they don't +// need brand checking. +assertEq(b.ef(`this.#x = 'Bye'; this.#x`), 'Bye haha'); +assertEq(b.ef(`var x = () => { this.#x = 'Hi'; return this.#x}; x()`), 'Hi haha'); + + +// // Private methods require very special brand checking. +assertEq(b.ef(`this.#priv()`), 12); +assertEq(b.ef(`let hello; +let f = () => { + hello = this.#priv(); + assertEq(hello, 12); +}; +f(); +hello`), 12); +assertEq(b.layerEf(`this.#priv()`), 12); +assertEq(b.moreLayerEf(`this.#priv()`), 12); + +if ('dis' in this) { + // Ensure disassembly of GetAliasedDebugVar wroks. + assertEq(b.ef(`dis(); this.#priv()`), 12); +} + +assertEq(b.ef(`var x = () => { return this.#priv(); }; x()`), 12); +assertEq(b.ef(`function x(o) { function y(o) { return o.#priv(); }; return y(o); } x(this)`), 12); + +assertEq(b.ef("B.#smethod()"), 14) +assertEq(b.ef("B.#unusedmethod()"), 19); +assertEq(b.ef("B.#unusedgetter"), 10); + +b.ef("B.#unusedsetter = 19"); +assertEq(B.setter, 19); + +assertEq(B.f(), 14); +assertEq(B.sef(`this.#smethod()`), 14); +assertEq(B.sLayerEf(`this.#smethod()`), 14); +assertEq(B.sef("this.#unusedmethod()"), 19); +assertEq(B.sef("this.#unusedgetter"), 10); + + +B.sef("this.#unusedsetter = 13"); +assertEq(B.setter, 13); + +// Test case variant from Arai. +class C { + #priv() { + return 12; + } + + efInFunction(str) { + return (() => { + let self = this; + return evalInFrame(0, str); + })(); + } +} +c = new C; +assertEq(c.efInFunction(`self.#priv()`), 12); + +// JIT testing +assertEq(b.ef(` +let result; +let f = () => { + result = this.#priv(); + assertEq(result, 12); +}; +for (let i = 0; i < 1000; i++) { + f(); +} +result +`), 12); + +assertEq(b.ef("function f(o) { return o.callPriv() }; for (let i = 0; i < 1000; i++) { f(this); } f(this)"), 12); +assertEq(b.ef("function f(o) { return o.callPrivF() }; for (let i = 0; i < 1000; i++) { f(this); } f(this)"), 12); +assertEq(b.ef(`function x(o) { function y(o) { return o.#priv(); }; return y(o); } x(this)`), 12); + +assertEq(B.sef(`function f(o) { return o.#smethod() }; for (let i = 0; i < 1000; i ++) { f(this); }; f(this)`), 14); + +assertEq(b.ef(` +var x = () => { + return (() => { + return (() => { + let a; + return (() => { + let b = a; + return this.#priv(); + })(); + })(); + })(); +}; +x() +`), 12);
\ No newline at end of file |