diff options
Diffstat (limited to 'js/src/jit-test/tests/self-hosting')
20 files changed, 312 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/self-hosting/GetStringDataProperty.js b/js/src/jit-test/tests/self-hosting/GetStringDataProperty.js new file mode 100644 index 0000000000..3eb2a9be7e --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/GetStringDataProperty.js @@ -0,0 +1,23 @@ +// Bug 1267364 - GetStringDataProperty should return undefined when the object +// is non-native. + +var GetStringDataProperty = getSelfHostedValue("GetStringDataProperty"); + +function testProxy() { + var obj = new Proxy({"foo": "10"}, {}); + var v = GetStringDataProperty(obj, "foo"); + assertEq(v, undefined); +} + +function testMaybeUnboxed() { + // Use JSON.parse to create unboxed object if availbale. + var obj = JSON.parse("[" + '{"foo": "10"},'.repeat(100) +"{}]"); + + // GetStringDataProperty may return "10" or undefined, depending on whether + // `obj` is unboxed or not + var v = GetStringDataProperty(obj[0], "foo"); + assertEq(v == undefined || v == "10", true); +} + +testProxy(); +testMaybeUnboxed(); diff --git a/js/src/jit-test/tests/self-hosting/bug1264575.js b/js/src/jit-test/tests/self-hosting/bug1264575.js new file mode 100644 index 0000000000..db74ef48c1 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/bug1264575.js @@ -0,0 +1,7 @@ +function f(x, [y]) {} +f(0, []); +// jsfunfuzz-generated +let i = 0; +for (var z of [0, 0, 0]) { + verifyprebarriers(); +} diff --git a/js/src/jit-test/tests/self-hosting/bug957004.js b/js/src/jit-test/tests/self-hosting/bug957004.js new file mode 100644 index 0000000000..ce767a9a4a --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/bug957004.js @@ -0,0 +1,3 @@ +// No result, just mustn't crash. +Array.prototype.push(0); +Array.prototype.indexOf(); diff --git a/js/src/jit-test/tests/self-hosting/define-value-property.js b/js/src/jit-test/tests/self-hosting/define-value-property.js new file mode 100644 index 0000000000..b5ffebde21 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/define-value-property.js @@ -0,0 +1,8 @@ +// These tests just mustn't trigger asserts. +if (!this.hasOwnProperty('Intl')) + quit(); + +Object.prototype.get = 5; +new Intl.Collator().resolvedOptions(); + +Intl.DateTimeFormat.supportedLocalesOf('en'); diff --git a/js/src/jit-test/tests/self-hosting/get-backtrace-in-constructing-bound-function.js b/js/src/jit-test/tests/self-hosting/get-backtrace-in-constructing-bound-function.js new file mode 100644 index 0000000000..10cc1b3217 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/get-backtrace-in-constructing-bound-function.js @@ -0,0 +1,6 @@ +function t() { + getBacktrace({ locals: true }); +} +var f = t.bind(); +new f(); +f(); diff --git a/js/src/jit-test/tests/self-hosting/get-intrinsic.js b/js/src/jit-test/tests/self-hosting/get-intrinsic.js new file mode 100644 index 0000000000..8cff55a5cd --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/get-intrinsic.js @@ -0,0 +1,19 @@ + +var intrinsic_names = [ + "IsConstructor", // Implementation in C++ + "ArrayMap", // Implementation in JS + "localeCache", // Self-hosting variable +]; + +for (var name of intrinsic_names) { + // GetIntrinsic in same global should have consistent values + assertEq(getSelfHostedValue(name), getSelfHostedValue(name)); + + // Different globals shouldn't reuse intrinsics. + for (var newCompartment of [true, false]) { + let g = newGlobal({newCompartment}); + let a = evaluate(`getSelfHostedValue("${name}")`, { global: g }) + let b = getSelfHostedValue(name); + assertEq(a === b, false); + } +} diff --git a/js/src/jit-test/tests/self-hosting/intl-fallback-original.js b/js/src/jit-test/tests/self-hosting/intl-fallback-original.js new file mode 100644 index 0000000000..456084d5d6 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/intl-fallback-original.js @@ -0,0 +1,9 @@ +// |jit-test| skip-if: typeof Intl === 'undefined'; skip-if: getBuildConfiguration()['wasi'] + +// Clobbering `Symbol` should not impact creation of %Intl%.[[FallbackSymbol]] +globalThis.Symbol = null; + +const IntlFallbackSymbol = + Object.getOwnPropertySymbols( + Intl.DateTimeFormat.call( + Object.create(Intl.DateTimeFormat.prototype)))[0]; diff --git a/js/src/jit-test/tests/self-hosting/invoke-self-hosted-function.js b/js/src/jit-test/tests/self-hosting/invoke-self-hosted-function.js new file mode 100644 index 0000000000..88893c58bd --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/invoke-self-hosted-function.js @@ -0,0 +1,9 @@ +var callees = [function a() {}, function b() {}, function c() {}, function d() {}, Array.prototype.forEach]; + +function f() { + for (var i = 0; i < callees.length; ++i) { + callees[i](function(){}); + } +} + +f();
\ No newline at end of file diff --git a/js/src/jit-test/tests/self-hosting/invoke-self-hosted-with-primitive-this.js b/js/src/jit-test/tests/self-hosting/invoke-self-hosted-with-primitive-this.js new file mode 100644 index 0000000000..24130e0f01 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/invoke-self-hosted-with-primitive-this.js @@ -0,0 +1,7 @@ +try { + [0,0].sort(Array.some) + "".replace(RegExp(), Array.reduce) +} catch (error) { + if (!(error instanceof TypeError && /^\w is not a function$/.test(error.message))) + throw error; +} diff --git a/js/src/jit-test/tests/self-hosting/is-constructor-inlined.js b/js/src/jit-test/tests/self-hosting/is-constructor-inlined.js new file mode 100644 index 0000000000..e801a4b58e --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/is-constructor-inlined.js @@ -0,0 +1,16 @@ +var g = newGlobal(); +var w = g.eval("() => {}"); +var v = g.eval("Array"); + +function f() +{ + try { + Reflect.construct(v, {}, w); + } catch (e) { + assertEq(e instanceof TypeError, true); + } +} + +f(); +f(); +f(); diff --git a/js/src/jit-test/tests/self-hosting/is-constructor-on-wrapper.js b/js/src/jit-test/tests/self-hosting/is-constructor-on-wrapper.js new file mode 100644 index 0000000000..51ece0fe4b --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/is-constructor-on-wrapper.js @@ -0,0 +1,17 @@ +var g = newGlobal(); +var w = g.eval("() => {}"); +var v = g.eval("Array"); + +try { + Reflect.construct(Array, [], w); + assertEq(true, false, "Expected exception above"); +} catch (e) { + assertEq(e.constructor, TypeError); +} + +try { + Reflect.construct(v, [], w); + assertEq(true, false, "Expected exception above"); +} catch (e) { + assertEq(e.constructor, TypeError); +} diff --git a/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js b/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js new file mode 100644 index 0000000000..fd2244be21 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js @@ -0,0 +1,91 @@ +var IsPossiblyWrappedTypedArray = getSelfHostedValue("IsPossiblyWrappedTypedArray"); + +var declareSamples = ` + var allTypedArraySamples = [ + { value: new Int8Array(1), expected: true }, + { value: new Uint8Array(1), expected: true }, + { value: new Int16Array(1), expected: true }, + { value: new Uint16Array(1), expected: true }, + { value: new Int32Array(1), expected: true }, + { value: new Uint32Array(1), expected: true }, + { value: new Float32Array(1), expected: true }, + { value: new Float64Array(1), expected: true }, + { value: new Uint8ClampedArray(1), expected: true } + ]; + + var allObjectSamples = [ + { value: new Array(1), expected: false }, + { value: {}, expected: false }, + { value: { length: 1 }, expected: false } + ]; +`; + +// Create a new global to wrap with cross compartment wrappers. +var g = newGlobal(); +evaluate(declareSamples) +g.evaluate(declareSamples); + +var assertCode = `function (value, expected) { + assertEq(IsPossiblyWrappedTypedArray(value), expected); + return inIon(); +}`; + +function checkSamples(samples) { + // Create the assert function anew every run so as not to share JIT code, + // type information, etc. + var assert = new Function(`return (${assertCode})`)(); + + // Prevent Ion compilation of this function so that we don't freeze the + // sample array's type. If we did, IonBuilder's typed-array-length inlining + // would always see a Mixed state, preventing IsPossiblyWrappedTypedArray + // from being inlined. + with ({}) {}; + + do { + // spinInJit is used to ensure that we at least test all elements in the + // sample vector while running a compiled version of the assert + // function. + var spinInJit = true; + for (var i = 0; i < samples.length; i++) { + var e = samples[i]; + if (!e) continue; + spinInJit = spinInJit && assert(e.value, e.expected); + } + } while(!spinInJit); +} + +// Check a mix of samples from each type. +function test(a, b, c, d) { + var samples = [ + a == -1 ? null : allTypedArraySamples[a], + b == -1 ? null : allObjectSamples[b], + c == -1 ? null : g.allTypedArraySamples[c], + d == -1 ? null : g.allObjectSamples[d], + ]; + + checkSamples(samples); +} + +// Check all samples. +checkSamples(allTypedArraySamples); +checkSamples(allObjectSamples); +checkSamples(g.allTypedArraySamples); +checkSamples(g.allObjectSamples); + +// Check combinations mixing 2 elements from different types. +test(-1, -1, 0, 0); +test(-1, 0, -1, 0); +test(-1, 0, 0, -1); +test( 0, -1, -1, 0); +test( 0, -1, 0, -1); +test( 0, 0, -1, -1); +test( 0, 0, -1, 0); + +// Check combinations mixing 3 elements from different types. +test(-1, 0, 0, 0); +test( 0, -1, 0, 0); +test( 0, 0, -1, 0); +test( 0, 0, 0, -1); + +// Check combinations mixing 4 elements from different types. +test( 0, 0, 0, 0); diff --git a/js/src/jit-test/tests/self-hosting/makeconstructible-function-inherited-prototype-property.js b/js/src/jit-test/tests/self-hosting/makeconstructible-function-inherited-prototype-property.js new file mode 100644 index 0000000000..ff4d0c000a --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/makeconstructible-function-inherited-prototype-property.js @@ -0,0 +1,3 @@ +var proxy = new Proxy({ get: function() { throw 42; } }, {}); +Function.prototype.__proto__ = proxy; +this.hasOwnProperty("Intl"); diff --git a/js/src/jit-test/tests/self-hosting/method-called-on-incompatible.js b/js/src/jit-test/tests/self-hosting/method-called-on-incompatible.js new file mode 100644 index 0000000000..2a48991f66 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/method-called-on-incompatible.js @@ -0,0 +1,9 @@ +load(libdir + "asserts.js"); + +assertTypeErrorMessage(() => Set.prototype.forEach.call({}), "forEach method called on incompatible Object"); +assertTypeErrorMessage(() => newGlobal({newCompartment: true}).Set.prototype.forEach.call({}), "forEach method called on incompatible Object"); +assertTypeErrorMessage(() => Set.prototype.forEach.call(15), "forEach method called on incompatible number"); + +assertTypeErrorMessage(() => Int8Array.prototype.find.call({}), "find method called on incompatible Object"); +assertTypeErrorMessage(() => newGlobal({newCompartment: true}).Int8Array.prototype.find.call({}), "find method called on incompatible Object"); +assertTypeErrorMessage(() => Int8Array.prototype.find.call(15), "find method called on incompatible number"); diff --git a/js/src/jit-test/tests/self-hosting/object-define-hazard.js b/js/src/jit-test/tests/self-hosting/object-define-hazard.js new file mode 100644 index 0000000000..7a1ccc2243 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/object-define-hazard.js @@ -0,0 +1,18 @@ +// We shouldn't do the wrong thing in the face of an evil Object.prototype + +Object.prototype.get = function() {}; +var x = {}; +var setter = function () {}; +x.__defineSetter__("a", setter); +var desc = Object.getOwnPropertyDescriptor(x, "a"); +assertEq(desc.get, undefined); +assertEq(desc.set, setter); +delete Object.prototype.get; + +Object.prototype.set = function() {}; +x = {}; +var getter = function () {}; +x.__defineGetter__("a", getter); +desc = Object.getOwnPropertyDescriptor(x, "a"); +assertEq(desc.set, undefined); +assertEq(desc.get, getter); diff --git a/js/src/jit-test/tests/self-hosting/object-lookup-hazard.js b/js/src/jit-test/tests/self-hosting/object-lookup-hazard.js new file mode 100644 index 0000000000..5197a9113d --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/object-lookup-hazard.js @@ -0,0 +1,8 @@ +// We shouldn't do the wrong thing in the face of an evil Object.prototype + +Object.prototype.get = function() {}; +assertEq(({a: 1}).__lookupGetter__("a"), undefined); +delete Object.prototype.get; + +Object.prototype.set = function() {}; +assertEq(({a: 1}).__lookupSetter__("a"), undefined); diff --git a/js/src/jit-test/tests/self-hosting/oom-delazify.js b/js/src/jit-test/tests/self-hosting/oom-delazify.js new file mode 100644 index 0000000000..2c9bfc71e9 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/oom-delazify.js @@ -0,0 +1,5 @@ +// |jit-test| --no-blinterp; skip-if: !('oomTest' in this) + +// Disable the JITs to make oomTest more reliable + +oomTest(() => Object.bind()) diff --git a/js/src/jit-test/tests/self-hosting/oom-toplevel.js b/js/src/jit-test/tests/self-hosting/oom-toplevel.js new file mode 100644 index 0000000000..60f2be4e1e --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/oom-toplevel.js @@ -0,0 +1,25 @@ +// |jit-test| skip-if: !('oomAtAllocation' in this) + +function code(n) { + return ` + // Trigger top-level execution with an OOM in the middle. + oomAtAllocation(${n}); + try { getSelfHostedValue("numberFormatCache") } catch (e) { } + resetOOMFailure(); + + // Read current value of "dateTimeFormatCache". + var initVal = getSelfHostedValue("dateTimeFormatCache"); + assertEq(typeof initVal, "object"); + + // Retrigger top-level execution by reading a later value in the file. + // Then compare that "dateTimeFormatCache" was not clobbered. + getSelfHostedValue("collatorCache"); + assertEq(initVal, getSelfHostedValue("dateTimeFormatCache")); + `; +} + +// We cannot use `oomTest` here because of divergence issues from things like +// `RegisterShapeCache` absorbing OOMs. +for (var i = 1; i < 300; ++i) { + evaluate(code(i), { global: newGlobal() }); +} diff --git a/js/src/jit-test/tests/self-hosting/relazify.js b/js/src/jit-test/tests/self-hosting/relazify.js new file mode 100644 index 0000000000..b335f8026c --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/relazify.js @@ -0,0 +1,16 @@ +// |jit-test| skip-if: isLcovEnabled() + +// Self-hosted builtins use a special form of lazy function, but still can be +// delazified in some cases. + +let obj = []; +let fun = obj.map; +assertEq(isLazyFunction(fun), true); + +// Delazify +fun.call(obj, x => x); +assertEq(isLazyFunction(fun), false); + +// Relazify +relazifyFunctions(obj); +assertEq(isLazyFunction(fun), true); diff --git a/js/src/jit-test/tests/self-hosting/tolength.js b/js/src/jit-test/tests/self-hosting/tolength.js new file mode 100644 index 0000000000..06fda18a72 --- /dev/null +++ b/js/src/jit-test/tests/self-hosting/tolength.js @@ -0,0 +1,13 @@ +let ToLength = getSelfHostedValue('ToLength'); + +assertEq(ToLength(NaN), 0); +assertEq(ToLength(-0), 0); +assertEq(ToLength(0), 0); +assertEq(ToLength(-Infinity), 0); +assertEq(ToLength(-Math.pow(2, 31)), 0); + +const MAX = Math.pow(2, 53) - 1; +assertEq(ToLength(Infinity), MAX); +assertEq(ToLength(MAX + 1), MAX); +assertEq(ToLength(3), 3); +assertEq(ToLength(40.5), 40); |