mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
test: add JSC JIT stress tests from WebKit (#26380)
## Summary This PR adds 78 stress tests that exercise JSC's JIT compilation tiers. The tests are ported from WebKit's `JSTests/stress/` and `JSTests/wasm/stress/` directories, covering all five JIT tiers: - **FTL** (41 tests): math intrinsics, string ops, regexp, arguments, exceptions, try-catch, property access, OSR, tail calls - **DFG** (14 tests): SSA, type conversion, strength reduction, arguments, internal functions, try-catch, class constructors - **Allocation sinking / OSR / LICM** (6 tests): varargs, loop unrolling, LICM - **Wasm BBQ** (11 tests): fused-if register alloc, OSR with exceptions, ipint-bbq OSR, tail calls - **Wasm OMG** (6 tests): recompile, OSR stack slots, tail call clobber Each test exercises hot loops that trigger JIT tier-up, verifying correctness of JIT-compiled code. ## Motivation The goal is to improve stability on platforms that Bun supports but are not covered by WebKit's EWS (Early Warning System). By running these JIT stress tests across all CI platforms, we can catch JIT-related regressions that would otherwise go unnoticed. ## Licensing Since the test fixtures are derived from WebKit's `JSTests/`, a `LICENSE` file is included in the test directory with the BSD 2-Clause license per WebKit's contribution policy. ## Next Steps As a follow-up, we are considering running these tests specifically under CPU emulation (without AVX) on baseline builds, to verify that JIT-generated code does not emit AVX instructions on platforms that do not support them. --------- Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
This commit is contained in:
30
test/js/bun/jsc-stress/LICENSE
Normal file
30
test/js/bun/jsc-stress/LICENSE
Normal file
@@ -0,0 +1,30 @@
|
||||
The test fixtures in this directory are derived from WebKit's JSTests:
|
||||
- fixtures/*.js from WebKit/JSTests/stress/
|
||||
- fixtures/wasm/*.js from WebKit/JSTests/wasm/stress/
|
||||
|
||||
These files are licensed under the BSD 2-Clause License, per WebKit's
|
||||
contribution policy for new code.
|
||||
|
||||
---
|
||||
|
||||
Copyright (C) 2014-2024 Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
5
test/js/bun/jsc-stress/bunfig.toml
Normal file
5
test/js/bun/jsc-stress/bunfig.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
[run]
|
||||
preload = "./preload.js"
|
||||
|
||||
[test]
|
||||
preload = "./preload.js"
|
||||
91
test/js/bun/jsc-stress/fixtures/dfg-ai-fold-bigint.js
Normal file
91
test/js/bun/jsc-stress/fixtures/dfg-ai-fold-bigint.js
Normal file
@@ -0,0 +1,91 @@
|
||||
// @bun
|
||||
function shouldBe(actual, expected) {
|
||||
if (actual !== expected)
|
||||
throw new Error('bad value: ' + actual);
|
||||
}
|
||||
|
||||
function allAreTrue(list)
|
||||
{
|
||||
for (let item of list)
|
||||
shouldBe(item, true);
|
||||
}
|
||||
|
||||
function allAreFalse(list)
|
||||
{
|
||||
for (let item of list)
|
||||
shouldBe(item, false);
|
||||
}
|
||||
|
||||
function lessThan()
|
||||
{
|
||||
return [0n < 2n, -10n < 20n, -10n < -2n, -100000000000000n < 0n, -100000000000000n < 10000n, -100000000000000n < -10000n, -1000000000000000000000n < -100000000000n, 1000000000000000000000n < 1000000000000000000000000n];
|
||||
}
|
||||
noInline(lessThan);
|
||||
|
||||
function lessThanFalse()
|
||||
{
|
||||
return [100000000000000000000n < 100000000000000000000n, 0n < 0n, 2n < 0n, 2n < 2n, -10n < -10n, 20n < -20n, -2n < -10n, 0n < -100000000000000n, -10000n < -100000000000000n, -100000000000n < -1000000000000000000000n, 1000000000000000000000000n < 1000000000000000000000n ];
|
||||
}
|
||||
noInline(lessThanFalse);
|
||||
|
||||
function lessThanEqual()
|
||||
{
|
||||
return [100000000000000000000n <= 100000000000000000000n, 0n <= 0n, 0n <= 2n, 2n <= 2n, -10n <= -10n, -20n <= 20n, -10n <= -2n, -100000000000000n <= 0n, -100000000000000n <= -10000n, -1000000000000000000000n <= -100000000000n, 1000000000000000000000n <= 1000000000000000000000000n ];
|
||||
}
|
||||
noInline(lessThanEqual);
|
||||
|
||||
function lessThanEqualFalse()
|
||||
{
|
||||
return [100000000000000000001n <= 100000000000000000000n, 1n <= 0n, 2n <= 0n, 3n <= 2n, -10n <= -11n, 20n <= -20n, -2n <= -10n, 0n <= -100000000000000n, -10000n <= -100000000000000n, -100000000000n <= -1000000000000000000000n, 1000000000000000000000000n <= 1000000000000000000000n ];
|
||||
}
|
||||
noInline(lessThanEqualFalse);
|
||||
|
||||
function greaterThan()
|
||||
{
|
||||
return [2n > 0n, 20n > -10n, -2n > -10n, 0n > -100000000000000n, 10000n > -100000000000000n, -10000n > -100000000000000n, -100000000000n > -1000000000000000000000n, 1000000000000000000000000n > 1000000000000000000000n ];
|
||||
}
|
||||
noInline(greaterThan);
|
||||
|
||||
function greaterThanFalse()
|
||||
{
|
||||
return [100000000000000000000n > 100000000000000000000n, 0n > 0n, 0n > 2n, 2n > 2n, -10n > -10n, -20n > 20n, -10n > -2n, -100000000000000n > 0n, -100000000000000n > -10000n, -1000000000000000000000n > -100000000000n, 1000000000000000000000n > 1000000000000000000000000n ];
|
||||
}
|
||||
noInline(greaterThanFalse);
|
||||
|
||||
function greaterThanEqual()
|
||||
{
|
||||
return [100000000000000000000n >= 100000000000000000000n, 0n >= 0n, 2n >= 0n, 2n >= 2n, -10n >= -10n, 20n >= -20n, -2n >= -10n, 0n >= -100000000000000n, -10000n >= -100000000000000n, -100000000000n >= -1000000000000000000000n, 1000000000000000000000000n >= 1000000000000000000000n ];
|
||||
}
|
||||
noInline(greaterThanEqual);
|
||||
|
||||
function greaterThanEqualFalse()
|
||||
{
|
||||
return [100000000000000000000n >= 100000000000000000001n, 0n >= 1n, 0n >= 2n, 2n >= 3n, -11n >= -10n, -20n >= 20n, -10n >= -2n, -100000000000000n >= 0n, -100000000000000n >= -10000n, -1000000000000000000000n >= -100000000000n, 1000000000000000000000n >= 1000000000000000000000000n ];
|
||||
}
|
||||
noInline(greaterThanEqualFalse);
|
||||
|
||||
function equal()
|
||||
{
|
||||
return [100000000000000000000n == 100000000000000000000n, 0n == 0n, 2n == 2n, -2n == -2n, -20n == -20n, -100000000000000n == -100000000000000n];
|
||||
}
|
||||
noInline(equal);
|
||||
|
||||
function equalFalse()
|
||||
{
|
||||
return [100000000000000000001n == 100000000000000000000n, 1n == 0n, -2n == 2n, 2n == -2n, -20n == 20n, -100000000000000n == 100000000000000n, 100000000000000n == -100000000000000n, -100000000000001n == -100000000000000n, 100000000000001n == 100000000000000n, -100000000000000n == 1n, 100000000000000n == 1n, -1n == 100000000000000n, 1n == -100000000000000n, -1n == -100000000000000n];
|
||||
}
|
||||
noInline(equalFalse);
|
||||
|
||||
for (var i = 0; i < 1e4; ++i) {
|
||||
allAreTrue(lessThan());
|
||||
allAreTrue(lessThanEqual());
|
||||
allAreTrue(greaterThan());
|
||||
allAreTrue(greaterThanEqual());
|
||||
allAreTrue(equal());
|
||||
|
||||
allAreFalse(lessThanFalse());
|
||||
allAreFalse(lessThanEqualFalse());
|
||||
allAreFalse(greaterThanFalse());
|
||||
allAreFalse(greaterThanEqualFalse());
|
||||
allAreFalse(equalFalse());
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
class Foo extends Promise { }
|
||||
|
||||
noInline(Foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var completed = false;
|
||||
try {
|
||||
Foo();
|
||||
completed = true;
|
||||
} catch (e) {
|
||||
}
|
||||
if (completed)
|
||||
throw "Error: completed without throwing";
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// @bun
|
||||
var foo = function(o) {
|
||||
var a = Array.prototype.slice.call(arguments);
|
||||
var sum = 0;
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
sum += a[i].x;
|
||||
return sum;
|
||||
};
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var niters = 10000;
|
||||
var total = 0;
|
||||
var o = {x: 42};
|
||||
for (var i = 0; i < niters; ++i) {
|
||||
total += foo(o, o, o);
|
||||
}
|
||||
|
||||
if (total != 42 * 3 * niters)
|
||||
throw new Error("Incorrect result!");
|
||||
@@ -0,0 +1,28 @@
|
||||
// @bun
|
||||
function f() {
|
||||
return 20;
|
||||
}
|
||||
noInline(f);
|
||||
|
||||
function bar(b) {
|
||||
if (b)
|
||||
throw new Error("blah!");
|
||||
}
|
||||
|
||||
function Foo(b) {
|
||||
try {
|
||||
this.value = bar(b);
|
||||
} catch(e) {
|
||||
this.value = e.toString();
|
||||
}
|
||||
|
||||
f(this.value, b);
|
||||
}
|
||||
noInline(Foo);
|
||||
|
||||
|
||||
for (var i = 1; i < 1000; i++) {
|
||||
let value = new Foo(i % 3 === 0);
|
||||
if (i % 3 === 0 && value.value !== "Error: blah!")
|
||||
throw new Error("bad value: " + value.value);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function shouldBe(actual, expected) {
|
||||
if (actual !== expected)
|
||||
throw new Error('bad value: ' + actual);
|
||||
}
|
||||
noInline(shouldBe);
|
||||
|
||||
function target(func)
|
||||
{
|
||||
return func();
|
||||
}
|
||||
noInline(target);
|
||||
|
||||
for (var i = 0; i < 1e4; ++i)
|
||||
shouldBe(target(Array).length, 0);
|
||||
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function shouldBe(actual, expected) {
|
||||
if (actual !== expected)
|
||||
throw new Error('bad value: ' + actual);
|
||||
}
|
||||
noInline(shouldBe);
|
||||
|
||||
function target(func)
|
||||
{
|
||||
return new func();
|
||||
}
|
||||
noInline(target);
|
||||
|
||||
for (var i = 0; i < 1e4; ++i)
|
||||
shouldBe(target(Array).length, 0);
|
||||
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function doIndexOf(a) {
|
||||
a.indexOf(a);
|
||||
}
|
||||
|
||||
function bar(f) {
|
||||
f();
|
||||
}
|
||||
|
||||
let array = [20];
|
||||
for (let i = 0; i < testLoopCount; ++i) {
|
||||
bar(() => {
|
||||
return doIndexOf(array.concat());
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// @bun
|
||||
//@ runDefault("--useConcurrentJIT=0", "--jitPolicyScale=0.001")
|
||||
|
||||
function shouldBe(actual, expected) {
|
||||
if (String(actual) !== expected)
|
||||
throw new Error('bad value: ' + actual);
|
||||
}
|
||||
noInline(shouldBe);
|
||||
|
||||
const arr = [[11, 22, 33]];
|
||||
class CC {
|
||||
constructor(a) {
|
||||
[a] = arr;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
shouldBe(a, `11,22,33`);
|
||||
}
|
||||
const c = [53255];
|
||||
c[8] = 2;
|
||||
}
|
||||
}
|
||||
new CC();
|
||||
new CC();
|
||||
@@ -0,0 +1,105 @@
|
||||
// @bun
|
||||
// Test that a object accepts DFG PutByValueDirect operation with edge numbers.
|
||||
|
||||
function lookupWithKey(key) {
|
||||
var object = {
|
||||
[key]: 42
|
||||
};
|
||||
return object[key];
|
||||
}
|
||||
noInline(lookupWithKey);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
[
|
||||
// integers
|
||||
-0x80000001, // out of int32_t
|
||||
-0x80000000, // int32_t min
|
||||
-1, // negative
|
||||
0, // zero
|
||||
1, // positive
|
||||
0x7fffffff, // int32_t max
|
||||
0x80000000, // out of int32_t
|
||||
0xfffffffd, // less than array max in JSObject
|
||||
0xfffffffe, // array max in JSObject
|
||||
0xffffffff, // uint32_t max, not array index
|
||||
0x100000000, // out of uint32_t
|
||||
|
||||
// stringified integers
|
||||
(-0x80000001).toString(), // out of int32_t
|
||||
(-0x80000000).toString(), // int32_t min
|
||||
(-1).toString(), // negative
|
||||
(0).toString(), // zero
|
||||
(1).toString(), // positive
|
||||
(0x7fffffff).toString(), // int32_t max
|
||||
(0x80000000).toString(), // out of int32_t
|
||||
(0xfffffffd).toString(), // less than array max in JSObject
|
||||
(0xfffffffe).toString(), // array max in JSObject
|
||||
(0xffffffff).toString(), // (uint32_t max).toString()
|
||||
(0x100000000).toString(), // out of uint32_t
|
||||
|
||||
// doubles
|
||||
Number.MIN_VALUE,
|
||||
Number.MAX_VALUE,
|
||||
Number.MIN_SAFE_INTEGER,
|
||||
Number.MAX_SAFE_INTEGER,
|
||||
Number.POSITIVE_INFINITY,
|
||||
Number.NEGATIVE_INFINITY,
|
||||
Number.NaN,
|
||||
Number.EPSILON,
|
||||
+0.0,
|
||||
-0.0,
|
||||
0.1,
|
||||
-0.1,
|
||||
4.2,
|
||||
-4.2,
|
||||
0x80000000 + 0.5, // out of int32_t, double
|
||||
|
||||
// stringified doules
|
||||
(Number.MIN_VALUE).toString(),
|
||||
(Number.MAX_VALUE).toString(),
|
||||
(Number.MIN_SAFE_INTEGER).toString(),
|
||||
(Number.MAX_SAFE_INTEGER).toString(),
|
||||
(Number.POSITIVE_INFINITY).toString(),
|
||||
(Number.NEGATIVE_INFINITY).toString(),
|
||||
"NaN",
|
||||
(Number.EPSILON).toString(),
|
||||
"+0.0",
|
||||
"-0.0",
|
||||
"0.1",
|
||||
"-0.1",
|
||||
"4.2",
|
||||
"-4.2",
|
||||
(0x80000000 + 0.5).toString()
|
||||
].forEach(function (key) {
|
||||
var value = lookupWithKey(key);
|
||||
if (value !== 42)
|
||||
throw new Error('bad value: ' + value);
|
||||
});
|
||||
}
|
||||
|
||||
function lookupWithKey2(key) {
|
||||
var object = {
|
||||
[key]: 42
|
||||
};
|
||||
return object[key];
|
||||
}
|
||||
noInline(lookupWithKey2);
|
||||
|
||||
var toStringThrowsError = {
|
||||
toString: function () {
|
||||
throw new Error('ng');
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var error = null;
|
||||
try {
|
||||
lookupWithKey2(toStringThrowsError);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
if (!error)
|
||||
throw new Error('not thrown');
|
||||
if (String(error) !== 'Error: ng')
|
||||
throw new Error('bad error: ' + String(error));
|
||||
}
|
||||
10
test/js/bun/jsc-stress/fixtures/dfg-rare-data.js
Normal file
10
test/js/bun/jsc-stress/fixtures/dfg-rare-data.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// @bun
|
||||
function F () { this.inner = 42; };
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var x = new F(false);
|
||||
F.prototype = Object; // Force clearing of the function's rare data
|
||||
var result = x.inner;
|
||||
if (result !== 42)
|
||||
throw "Expected 42, got: " + result;
|
||||
}
|
||||
9
test/js/bun/jsc-stress/fixtures/dfg-ssa-swap.js
Normal file
9
test/js/bun/jsc-stress/fixtures/dfg-ssa-swap.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// @bun
|
||||
var i,c=0;
|
||||
function foo()
|
||||
{
|
||||
var a=1,b;for(i=0;i<2;++i){[a,b]=[b,a];c++}if(!a^b)throw c
|
||||
}
|
||||
noInline(foo);
|
||||
for(var k = 0; k < testLoopCount; ++k)
|
||||
foo()
|
||||
@@ -0,0 +1,12 @@
|
||||
// @bun
|
||||
function foo(num) {
|
||||
num |= 0;
|
||||
let x1 = num % -2147483648;
|
||||
let x2 = x1 % 5;
|
||||
|
||||
if (x2 > 5)
|
||||
throw "Error";
|
||||
}
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++)
|
||||
foo(i);
|
||||
@@ -0,0 +1,36 @@
|
||||
// @bun
|
||||
var shouldThrow = false;
|
||||
|
||||
// str concat generates op_to_primitive.
|
||||
function toPrimitiveTarget() {
|
||||
if (shouldThrow) {
|
||||
return Symbol('Cocoa');
|
||||
}
|
||||
return 'Cocoa';
|
||||
}
|
||||
noInline(toPrimitiveTarget);
|
||||
|
||||
function doToPrimitive() {
|
||||
var value = toPrimitiveTarget();
|
||||
return value + "Cappuccino" + value;
|
||||
}
|
||||
noInline(doToPrimitive);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = doToPrimitive();
|
||||
if (result !== "CocoaCappuccinoCocoa")
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
shouldThrow = true;
|
||||
|
||||
var didThrow;
|
||||
try {
|
||||
shouldThrow = true;
|
||||
doToPrimitive();
|
||||
} catch (e) {
|
||||
didThrow = e;
|
||||
}
|
||||
|
||||
if (String(didThrow) !== "TypeError: Cannot convert a symbol to a string")
|
||||
throw "Error: didn't throw or threw wrong exception: " + didThrow;
|
||||
@@ -0,0 +1,51 @@
|
||||
// @bun
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("bad value")
|
||||
}
|
||||
noInline(assert);
|
||||
|
||||
let oThrow = {
|
||||
x: 20,
|
||||
y: 40,
|
||||
z: 50,
|
||||
get f() { throw new Error("Hello World!"); }
|
||||
};
|
||||
|
||||
let o1 = {
|
||||
x: 20,
|
||||
f: 40
|
||||
};
|
||||
|
||||
let o2 = {
|
||||
x: 20,
|
||||
y: 50,
|
||||
f: 500,
|
||||
get f() { return 20; }
|
||||
};
|
||||
|
||||
function foo(f) {
|
||||
let o = f();
|
||||
try {
|
||||
o = o.f;
|
||||
} catch(e) {
|
||||
assert(o === oThrow); // Make sure this is not undefined.
|
||||
}
|
||||
}
|
||||
noInline(foo);
|
||||
|
||||
let i;
|
||||
let flag = false;
|
||||
function f() {
|
||||
if (flag)
|
||||
return oThrow;
|
||||
if (i % 2)
|
||||
return o1;
|
||||
return o2;
|
||||
}
|
||||
noInline(f);
|
||||
for (i = 0; i < testLoopCount; i++) {
|
||||
foo(f);
|
||||
}
|
||||
flag = true;
|
||||
foo(f);
|
||||
17
test/js/bun/jsc-stress/fixtures/ftl-arithcos.js
Normal file
17
test/js/bun/jsc-stress/fixtures/ftl-arithcos.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// @bun
|
||||
//@ skip if $hostOS == "windows"
|
||||
|
||||
function foo(x) {
|
||||
return Math.cos(x);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
let expected = foo(testLoopCount - 1);
|
||||
var j = 0;
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
j = foo(i);
|
||||
|
||||
if (expected != j) {
|
||||
throw "Error"
|
||||
}
|
||||
15
test/js/bun/jsc-stress/fixtures/ftl-arithsin.js
Normal file
15
test/js/bun/jsc-stress/fixtures/ftl-arithsin.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function foo(x) {
|
||||
return Math.sin(x);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var j = 0;
|
||||
let expected = foo(testLoopCount - 1);
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
j = foo(i);
|
||||
|
||||
if (expected != j) {
|
||||
throw "Error"
|
||||
}
|
||||
15
test/js/bun/jsc-stress/fixtures/ftl-arithsqrt.js
Normal file
15
test/js/bun/jsc-stress/fixtures/ftl-arithsqrt.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function foo(x) {
|
||||
return Math.sqrt(x);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
let expected = foo(testLoopCount - 1);
|
||||
var j = 0;
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
j = foo(i);
|
||||
|
||||
if (expected != j) {
|
||||
throw "Error"
|
||||
}
|
||||
15
test/js/bun/jsc-stress/fixtures/ftl-arithtan.js
Normal file
15
test/js/bun/jsc-stress/fixtures/ftl-arithtan.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// @bun
|
||||
function foo(x) {
|
||||
return Math.tan(x);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var expected = foo(testLoopCount - 1);
|
||||
var j = 0;
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
j = foo(i);
|
||||
|
||||
if (expected != j){
|
||||
throw `Error: ${j}`;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// @bun
|
||||
function foo(f, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = f();
|
||||
f = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
return {outcome: "return", values: [f, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
function bar() {
|
||||
return 107;
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
// Warm up foo().
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(bar);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var result;
|
||||
try {
|
||||
bar = function() {
|
||||
throw "Error42";
|
||||
}
|
||||
var result = foo(bar, 108);
|
||||
} catch (e) {
|
||||
if (e != "Error42")
|
||||
throw "Error at end: bad exception: " + e;
|
||||
result = {outcome: "exception"};
|
||||
}
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
60
test/js/bun/jsc-stress/fixtures/ftl-call-exception.js
Normal file
60
test/js/bun/jsc-stress/fixtures/ftl-call-exception.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// @bun
|
||||
function foo(f, p, args) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = f.apply(this, args);
|
||||
f = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [f, p, x, result]};
|
||||
}
|
||||
return {outcome: "return", values: [f, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
function bar(a, b, c) {
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
// Warm up foo().
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(bar, null, [105, 1, 1]);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
bar = function() {
|
||||
throw "Error42";
|
||||
}
|
||||
var result = foo(bar, 108, [105, 1, 1]);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== bar)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 101)
|
||||
throw "Error at end: bad values[3]: " + result.values[3];
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// @bun
|
||||
function foo(f, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = f();
|
||||
f = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [f, p, x, result]};
|
||||
}
|
||||
return {outcome: "return", values: [f, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
function bar() {
|
||||
return 107;
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
// Warm up foo().
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(bar);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
bar = function() {
|
||||
throw "Error42";
|
||||
}
|
||||
var result = foo(bar, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== bar)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 101)
|
||||
throw "Error at end: bad values[3]: " + result.values[3];
|
||||
|
||||
18
test/js/bun/jsc-stress/fixtures/ftl-checkin-variable.js
Normal file
18
test/js/bun/jsc-stress/fixtures/ftl-checkin-variable.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// @bun
|
||||
function foo(l,x){
|
||||
var t = l in x;
|
||||
return t;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var r;
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var z = { 'y' : i, 's' : i + 1 };
|
||||
z.s = 10;
|
||||
r = foo("s",z);
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
print ("Error: " + r);
|
||||
}
|
||||
18
test/js/bun/jsc-stress/fixtures/ftl-checkin.js
Normal file
18
test/js/bun/jsc-stress/fixtures/ftl-checkin.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// @bun
|
||||
function foo(x){
|
||||
var t = "s" in x;
|
||||
return t;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var r;
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var z = { 'y' : i, 's' : i + 1 };
|
||||
z.s = 10;
|
||||
r = foo(z);
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
print ("Error: " + r);
|
||||
}
|
||||
22
test/js/bun/jsc-stress/fixtures/ftl-force-osr-exit.js
Normal file
22
test/js/bun/jsc-stress/fixtures/ftl-force-osr-exit.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// @bun
|
||||
function foo(p, o) {
|
||||
var q = o.q;
|
||||
if (p)
|
||||
return q.f;
|
||||
return q.g;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var o = {q: {f: 41, g: 42}};
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(false, o);
|
||||
if (result != 42)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
var result = foo(true, o);
|
||||
if (result != 41)
|
||||
throw "Error: bad result at end: " + result;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// @bun
|
||||
function foo(o, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = o.f;
|
||||
o = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [o, p, x, result]};
|
||||
}
|
||||
return {outcome: "return", values: [o, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Warm up foo() with polymorphic objects and getters.
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o = {};
|
||||
o.__defineGetter__("f", function() {
|
||||
return 107;
|
||||
});
|
||||
if (i & 1)
|
||||
o["i" + i] = i; // Make it polymorphic.
|
||||
var result = foo(o);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var o = {};
|
||||
o.__defineGetter__("f", function() {
|
||||
throw "Error42";
|
||||
});
|
||||
var result = foo(o, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== o)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 101)
|
||||
throw "Error at end: bad values[3]: " + result.values[3];
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// @bun
|
||||
function foo(o, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = o.f;
|
||||
o = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [o, p, x, result]};
|
||||
}
|
||||
return {outcome: "return", values: [o, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Warm up foo() with polymorphic objects.
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o;
|
||||
o = {f:107};
|
||||
o["i" + i] = i; // Make it polymorphic.
|
||||
var result = foo(o);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var o = {};
|
||||
o.__defineGetter__("f", function() {
|
||||
throw "Error42";
|
||||
});
|
||||
var result = foo(o, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== o)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 101)
|
||||
throw "Error at end: bad values[3]: " + result.values[3];
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// @bun
|
||||
function foo(i) {
|
||||
return arguments[i];
|
||||
}
|
||||
|
||||
function bar(i) {
|
||||
return [arguments[i], foo(i, "one", 2, "three"), arguments[i]];
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
function arraycmp(a, b) {
|
||||
if (a.length != b.length)
|
||||
return false;
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var thingies = [i % 4, "one", 2, "three"];
|
||||
var otherThingies = [i % 4, "five", 6, "seven"];
|
||||
var result = bar(i % 4, "five", 6, "seven");
|
||||
if (!arraycmp(result, [otherThingies[i % 4], thingies[i % 4], otherThingies[i % 4]]))
|
||||
throw "Error: bad result for i = " + i + ": " + result;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// @bun
|
||||
function foo(i) {
|
||||
return arguments[i];
|
||||
}
|
||||
|
||||
function bar(i) {
|
||||
return foo(i, "one", 2, "three");
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var thingies = [i % 4, "one", 2, "three"];
|
||||
var result = bar(i % 4, "five", 6, "seven");
|
||||
if (result != thingies[i % 4])
|
||||
throw "Error: bad result for i = " + i + ": " + result;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @bun
|
||||
function foo(i) {
|
||||
return arguments[i];
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var thingies = [i % 4, "one", 2, "three"];
|
||||
var result = foo(i % 4, "one", 2, "three");
|
||||
if (result != thingies[i % 4])
|
||||
throw "Error: bad result for i = " + i + ": " + result;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// @bun
|
||||
function foo(){
|
||||
return arguments.length;
|
||||
}
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var r = foo(11, 12, 13, 18, 19, 20);
|
||||
if (r != 6) throw "Error: "+r;
|
||||
}
|
||||
|
||||
12
test/js/bun/jsc-stress/fixtures/ftl-getmyargumentslength.js
Normal file
12
test/js/bun/jsc-stress/fixtures/ftl-getmyargumentslength.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @bun
|
||||
function foo(){
|
||||
return arguments.length;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var r = foo(11, 12, 13, 18, 19, 20);
|
||||
if (r != 6) throw "Error: "+r;
|
||||
}
|
||||
|
||||
19
test/js/bun/jsc-stress/fixtures/ftl-has-a-bad-time.js
Normal file
19
test/js/bun/jsc-stress/fixtures/ftl-has-a-bad-time.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// @bun
|
||||
function foo(p) {
|
||||
return p ? [42] : null;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Make sure we think that foo() allocates int arrays.
|
||||
for (var i = 0; i < 100; ++i)
|
||||
foo(true);
|
||||
|
||||
// Now have a bad time.
|
||||
var array = new Array();
|
||||
Array.prototype.__defineSetter__("0", function() { });
|
||||
|
||||
// Finally, get foo() to compile in the FTL. But don't allocate anymore arrays.
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
foo(false);
|
||||
|
||||
14
test/js/bun/jsc-stress/fixtures/ftl-in-overflow.js
Normal file
14
test/js/bun/jsc-stress/fixtures/ftl-in-overflow.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// @bun
|
||||
function foo(o) {
|
||||
return "foo" in o;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o = {};
|
||||
o["i" + i] = 42;
|
||||
o.foo = 43;
|
||||
foo(o);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// @bun
|
||||
function foo(){
|
||||
var count = 100;
|
||||
var d = new DataView(new ArrayBuffer(count));
|
||||
|
||||
for (var i = 0; i < count / 4; i++){
|
||||
d.setInt32(i, i);
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; i++){
|
||||
d.setInt8(i, i);
|
||||
}
|
||||
var result = 0;
|
||||
for (var i = 0; i < count; i++){
|
||||
result += d.getInt8(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var r = 0;
|
||||
for (var i = 0 ; i < 50000; i++){
|
||||
r += foo();
|
||||
}
|
||||
|
||||
if (r != 247500000)
|
||||
throw "Bad result: " + r;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// @bun
|
||||
function foo(x){
|
||||
return Math.random(x);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var x = 0;
|
||||
|
||||
for (var i = 0 ; i < testLoopCount; i++){
|
||||
x = foo(i);
|
||||
}
|
||||
16
test/js/bun/jsc-stress/fixtures/ftl-library-substring.js
Normal file
16
test/js/bun/jsc-stress/fixtures/ftl-library-substring.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// @bun
|
||||
function foo(i, x){
|
||||
return x.substring( 2 , 5);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var x = "";
|
||||
|
||||
for (var i = 0 ; i < testLoopCount; i++){
|
||||
x = foo(i, "lkajsx");
|
||||
}
|
||||
|
||||
if (x != "ajs")
|
||||
throw "Error: bad substring: "+ x;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// @bun
|
||||
'use strict';
|
||||
|
||||
const object = {};
|
||||
|
||||
function opt() {
|
||||
return Object.keys(object);
|
||||
}
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++)
|
||||
opt();
|
||||
|
||||
const tmp = new Array();
|
||||
13
test/js/bun/jsc-stress/fixtures/ftl-negate-zero.js
Normal file
13
test/js/bun/jsc-stress/fixtures/ftl-negate-zero.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// @bun
|
||||
function foo(x) {
|
||||
return -x;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(0);
|
||||
if (1 / result != "-Infinity")
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// @bun
|
||||
function foo(arg) {
|
||||
try {
|
||||
return new Array(arg);
|
||||
} catch (e) {
|
||||
return "error42";
|
||||
}
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo(1);
|
||||
if (result.length != 1)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
var result = foo(-1);
|
||||
if (result != "error42")
|
||||
throw "Error: bad result at end: " + result;
|
||||
|
||||
63
test/js/bun/jsc-stress/fixtures/ftl-operation-exception.js
Normal file
63
test/js/bun/jsc-stress/fixtures/ftl-operation-exception.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// @bun
|
||||
function foo(o, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
result = o.f;
|
||||
o = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [o, p, x, result]};
|
||||
}
|
||||
return {outcome: "return", values: [o, p, x, result]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Warm up foo() with polymorphic objects and non-object types.
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o;
|
||||
var isObject = i & 1;
|
||||
if (isObject) {
|
||||
o = {f:107};
|
||||
o["i" + i] = i; // Make it polymorphic.
|
||||
} else
|
||||
o = 42;
|
||||
var result = foo(o);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (isObject) {
|
||||
if (result.values[3] !== 107)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
} else {
|
||||
if (result.values[3] !== void 0)
|
||||
throw "Error in loop: bad values[3]: " + result.values[3];
|
||||
}
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var result = foo(null, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 4)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== null)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if (result.values[3] !== 101)
|
||||
throw "Error at end: bad values[3]: " + result.values[3];
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// @bun
|
||||
function foo(o, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
o.f = x + p;
|
||||
o = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [o, p, x]};
|
||||
}
|
||||
return {outcome: "return", values: [o, p, x]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Warm up foo() with polymorphic objects and getters.
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o = {};
|
||||
o.__defineSetter__("f", function(value) {
|
||||
this._f = value;
|
||||
});
|
||||
if (i & 1)
|
||||
o["i" + i] = i; // Make it polymorphic.
|
||||
var result = foo(o);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 3)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (o._f != 102 + 103)
|
||||
throw "Error in loop: bad value of o._f: " + o._f;
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var o = {};
|
||||
o.__defineSetter__("f", function() {
|
||||
throw "Error42";
|
||||
});
|
||||
var result = foo(o, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 3)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== o)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
if ("_f" in o)
|
||||
throw "Error at end: o has _f.";
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// @bun
|
||||
function foo(o, p) {
|
||||
var x = 100;
|
||||
var result = 101;
|
||||
try {
|
||||
x = 102;
|
||||
p = 103;
|
||||
o.f = x + p;
|
||||
o = 104;
|
||||
p = 105;
|
||||
x = 106;
|
||||
} catch (e) {
|
||||
return {outcome: "exception", values: [o, p, x]};
|
||||
}
|
||||
return {outcome: "return", values: [o, p, x]};
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
// Warm up foo() with polymorphic objects and getters.
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var o = {};
|
||||
if (i & 1)
|
||||
o["i" + i] = i; // Make it polymorphic.
|
||||
var result = foo(o);
|
||||
if (result.outcome !== "return")
|
||||
throw "Error in loop: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 3)
|
||||
throw "Error in loop: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== 104)
|
||||
throw "Error in loop: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 105)
|
||||
throw "Error in loop: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 106)
|
||||
throw "Error in loop: bad values[2]: " + result.values[2];
|
||||
if (o.f != 102 + 103)
|
||||
throw "Error in loop: bad value of o.f: " + o.f;
|
||||
}
|
||||
|
||||
// Now throw an exception.
|
||||
var o = {};
|
||||
o.__defineSetter__("f", function() {
|
||||
throw "Error42";
|
||||
});
|
||||
var result = foo(o, 108);
|
||||
if (result.outcome !== "exception")
|
||||
throw "Error at end: bad outcome: " + result.outcome;
|
||||
if (result.values.length !== 3)
|
||||
throw "Error at end: bad number of values: " + result.values.length;
|
||||
if (result.values[0] !== o)
|
||||
throw "Error at end: bad values[0]: " + result.values[0];
|
||||
if (result.values[1] !== 103)
|
||||
throw "Error at end: bad values[1]: " + result.values[1];
|
||||
if (result.values[2] !== 102)
|
||||
throw "Error at end: bad values[2]: " + result.values[2];
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// @bun
|
||||
function foo(x){
|
||||
x.a0 = 0;
|
||||
x.a1 = 1;
|
||||
x.a2 = 2;
|
||||
x.a3 = 3;
|
||||
x.a4 = 4;
|
||||
x.a5 = 5;
|
||||
x.a6 = 6;
|
||||
x.a7 = 7;
|
||||
x.a8 = 8;
|
||||
x.a9 = 9;
|
||||
x.a10 = 10;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var c = {};
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var b = {};
|
||||
foo(b);
|
||||
c = b;
|
||||
}
|
||||
|
||||
for (var j = 0; j <= 10 ; ++j)
|
||||
if (c['a'+j] != j)
|
||||
throw "Error "+c['a'+j];
|
||||
|
||||
|
||||
18
test/js/bun/jsc-stress/fixtures/ftl-regexp-exec.js
Normal file
18
test/js/bun/jsc-stress/fixtures/ftl-regexp-exec.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// @bun
|
||||
function foo(s) {
|
||||
return /foo/.exec(s);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo("foo");
|
||||
if (!result)
|
||||
throw "Error: bad result for foo";
|
||||
if (result.length != 1)
|
||||
throw "Error: bad result for foo: " + result;
|
||||
if (result[0] != "foo")
|
||||
throw "Error: bad result for foo: " + result;
|
||||
if (foo("bar"))
|
||||
throw "Error: bad result for bar";
|
||||
}
|
||||
13
test/js/bun/jsc-stress/fixtures/ftl-regexp-test.js
Normal file
13
test/js/bun/jsc-stress/fixtures/ftl-regexp-test.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// @bun
|
||||
function foo(s) {
|
||||
return /foo/.test(s);
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
if (!foo("foo"))
|
||||
throw "Error: bad result for foo";
|
||||
if (foo("bar"))
|
||||
throw "Error: bad result for bar";
|
||||
}
|
||||
20
test/js/bun/jsc-stress/fixtures/ftl-shr-exception.js
Normal file
20
test/js/bun/jsc-stress/fixtures/ftl-shr-exception.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// @bun
|
||||
function foo(a, b) {
|
||||
try {
|
||||
return a >> b;
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo((i & 1) ? 32 : "32", 2);
|
||||
if (result !== 8)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
var result = foo({valueOf: function() { throw "error42"; }}, 2);
|
||||
if (result !== "error42")
|
||||
throw "Error: bad result at end: " + result;
|
||||
36
test/js/bun/jsc-stress/fixtures/ftl-string-equality.js
Normal file
36
test/js/bun/jsc-stress/fixtures/ftl-string-equality.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// @bun
|
||||
function makeString(char) {
|
||||
var result = "";
|
||||
for (var i = 0; i < 10; ++i)
|
||||
result += char;
|
||||
return result;
|
||||
}
|
||||
|
||||
var array = [ "a", "b", "c", "d" ];
|
||||
|
||||
for (var i = 0; i < array.length; ++i)
|
||||
array[i] = makeString(array[i]);
|
||||
|
||||
function foo(array, s) {
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
if (array[i] == s)
|
||||
return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var array2 = [ "a", "b", "c", "d", "e" ];
|
||||
|
||||
for (var i = 0; i < array2.length; ++i)
|
||||
array2[i] = makeString(array2[i]);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var index = i % array2.length;
|
||||
var result = foo(array, array2[index]);
|
||||
var expected = index >= array.length ? null : index
|
||||
if (result !== expected)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
19
test/js/bun/jsc-stress/fixtures/ftl-string-ident-equality.js
Normal file
19
test/js/bun/jsc-stress/fixtures/ftl-string-ident-equality.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// @bun
|
||||
var array = [ "a", "b", "c", "d" ];
|
||||
|
||||
function foo(array, s) {
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
if (array[i] == s)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var result = 0;
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
result += foo(array, "d");
|
||||
|
||||
if (result != testLoopCount)
|
||||
throw "Bad result: " + result;
|
||||
@@ -0,0 +1,36 @@
|
||||
// @bun
|
||||
function makeString(char) {
|
||||
var result = "";
|
||||
for (var i = 0; i < 10; ++i)
|
||||
result += char;
|
||||
return result;
|
||||
}
|
||||
|
||||
var array = [ "a", "b", "c", "d" ];
|
||||
|
||||
for (var i = 0; i < array.length; ++i)
|
||||
array[i] = makeString(array[i]);
|
||||
|
||||
function foo(array, s) {
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
if (array[i] === s)
|
||||
return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
var array2 = [ "a", "b", "c", "d", "e" ];
|
||||
|
||||
for (var i = 0; i < array2.length; ++i)
|
||||
array2[i] = makeString(array2[i]);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var index = i % array2.length;
|
||||
var result = foo(array, array2[index]);
|
||||
var expected = index >= array.length ? null : index
|
||||
if (result !== expected)
|
||||
throw "Error: bad result: " + result + " but expected " + expected;
|
||||
}
|
||||
|
||||
20
test/js/bun/jsc-stress/fixtures/ftl-sub-exception.js
Normal file
20
test/js/bun/jsc-stress/fixtures/ftl-sub-exception.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// @bun
|
||||
function foo(a, b) {
|
||||
try {
|
||||
return a - b;
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo((i & 1) ? 32 : "32", 10);
|
||||
if (result !== 22)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
var result = foo({valueOf: function() { throw "error42"; }}, 10);
|
||||
if (result !== "error42")
|
||||
throw "Error: bad result at end: " + result;
|
||||
21
test/js/bun/jsc-stress/fixtures/ftl-tail-call.js
Normal file
21
test/js/bun/jsc-stress/fixtures/ftl-tail-call.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @bun
|
||||
"use strict";
|
||||
|
||||
function foo(a, b, c) {
|
||||
return a + b * 2 + c * 3;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
function bar(a, b, c) {
|
||||
return foo(a.f, b.g, c.h);
|
||||
}
|
||||
|
||||
noInline(bar);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = bar({f: 4}, {g: 5}, {h: 6});
|
||||
if (result != 4 + 5 * 2 + 6 * 3)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// @bun
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("uh oh");
|
||||
}
|
||||
|
||||
let flag = false;
|
||||
let o = {
|
||||
valueOf() {
|
||||
if (flag)
|
||||
throw new Error("by by");
|
||||
return 13.5;
|
||||
}
|
||||
};
|
||||
noInline(o.valueOf);
|
||||
|
||||
function baz() { return 1.5; }
|
||||
noInline(baz);
|
||||
|
||||
function foo(x, o) {
|
||||
let r = baz();
|
||||
try {
|
||||
r = x - o - r;
|
||||
} catch(e) { }
|
||||
return r;
|
||||
}
|
||||
noInline(foo);
|
||||
|
||||
let x = 20.5;
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
assert(foo(x, o) === 5.5);
|
||||
}
|
||||
flag = true;
|
||||
assert(foo(x, o) === 1.5);
|
||||
|
||||
|
||||
function bar(x, o) {
|
||||
let caughtException = false;
|
||||
var r = null;
|
||||
try {
|
||||
// This tests aliasing of left/right with result register in a SubGenerator
|
||||
// and ensures that the sub will spill the register properly and that we value
|
||||
// recover properly.
|
||||
r = x - o;
|
||||
} catch(e) {
|
||||
caughtException = true;
|
||||
assert(r === null);
|
||||
}
|
||||
if (!caughtException)
|
||||
assert(r === 7);
|
||||
return caughtException;
|
||||
}
|
||||
noInline(bar);
|
||||
|
||||
flag = false;
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
assert(bar(x, o) === false);
|
||||
}
|
||||
flag = true;
|
||||
assert(bar(x, o) === true);
|
||||
@@ -0,0 +1,66 @@
|
||||
// @bun
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("bad value")
|
||||
}
|
||||
noInline(assert);
|
||||
|
||||
function random() {
|
||||
return "blah";
|
||||
}
|
||||
noInline(random);
|
||||
|
||||
function identity(x) {
|
||||
return x;
|
||||
}
|
||||
noInline(identity);
|
||||
|
||||
let o1 = {
|
||||
g: 20,
|
||||
y: 40,
|
||||
f: "get f"
|
||||
};
|
||||
|
||||
let o2 = {
|
||||
g: "g",
|
||||
y: "y",
|
||||
get f() {
|
||||
return "get f";
|
||||
}
|
||||
}
|
||||
|
||||
let o4 = {};
|
||||
|
||||
let o3 = {
|
||||
get f() {
|
||||
throw new Error("blah");
|
||||
}
|
||||
}
|
||||
|
||||
function foo(o, a) {
|
||||
let x = o.g;
|
||||
let y = o.y;
|
||||
let oo = identity(o);
|
||||
let j = random();
|
||||
try {
|
||||
j = o.f;
|
||||
} catch(e) {
|
||||
assert(j === "blah");
|
||||
assert(oo === o3);
|
||||
return x + y + 1;
|
||||
}
|
||||
return x + y;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
if (i % 3 == 0) {
|
||||
assert(foo(o1) === 60);
|
||||
} else if (i % 3 === 1) {
|
||||
assert(foo(o2) === "gy");
|
||||
} else {
|
||||
foo(o4);
|
||||
}
|
||||
}
|
||||
|
||||
foo(o3);
|
||||
@@ -0,0 +1,58 @@
|
||||
// @bun
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("bad value")
|
||||
}
|
||||
noInline(assert);
|
||||
|
||||
function random() {
|
||||
return "blah";
|
||||
}
|
||||
noInline(random);
|
||||
|
||||
function foo(o, a) {
|
||||
let x = o.g;
|
||||
let y = o.y;
|
||||
let j = random();
|
||||
try {
|
||||
j = o.f;
|
||||
} catch(e) {
|
||||
assert(j === "blah");
|
||||
return x + y + 1;
|
||||
}
|
||||
return x + y;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
var flag = false;
|
||||
function f(arg1, arg2, arg3) {
|
||||
if (flag)
|
||||
throw new Error("blah")
|
||||
return arg1;
|
||||
}
|
||||
noInline(f);
|
||||
let o1 = {
|
||||
g: 20,
|
||||
y: 40,
|
||||
f: "get f"
|
||||
};
|
||||
|
||||
let o2 = {
|
||||
g: "g",
|
||||
y: "y",
|
||||
get f() {
|
||||
if (flag)
|
||||
throw new Error("blah");
|
||||
return "get f";
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
if (i % 2) {
|
||||
assert(foo(o1) === 60);
|
||||
} else {
|
||||
assert(foo(o2) === "gy");
|
||||
}
|
||||
}
|
||||
flag = true;
|
||||
assert(foo(o2) === "gy1");
|
||||
@@ -0,0 +1,74 @@
|
||||
// @bun
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("Bad value.")
|
||||
}
|
||||
noInline(assert);
|
||||
|
||||
var v1 = 100;
|
||||
var v2 = 200;
|
||||
var flag = false;
|
||||
var o1 = {
|
||||
get f() {
|
||||
if (flag)
|
||||
throw new Error("gotcha!");
|
||||
return v1;
|
||||
}
|
||||
}
|
||||
|
||||
function a() { return "a"; }
|
||||
noInline(a);
|
||||
function b() { return "b"; }
|
||||
noInline(b);
|
||||
function c() { return "c"; }
|
||||
noInline(c);
|
||||
function d() { return "d"; }
|
||||
noInline(d);
|
||||
function e() { return "e"; }
|
||||
noInline(e);
|
||||
function f() { return "f"; }
|
||||
noInline(f);
|
||||
function g() { return "g"; }
|
||||
noInline(g);
|
||||
|
||||
var o2 = {
|
||||
get f() {
|
||||
assert(true);
|
||||
assert(true);
|
||||
assert(true);
|
||||
assert(true);
|
||||
assert(true);
|
||||
assert(true);
|
||||
assert(true);
|
||||
return v2;
|
||||
}
|
||||
}
|
||||
|
||||
function foo(o) {
|
||||
try {
|
||||
var _a = a();
|
||||
var _b = b();
|
||||
var _c = c();
|
||||
var _d = d();
|
||||
var _e = e();
|
||||
var _f = f();
|
||||
var _g = g();
|
||||
|
||||
o = o.f;
|
||||
|
||||
} catch(e) {
|
||||
assert(o === o1);
|
||||
assert(_b === "b");
|
||||
assert(_c === "c");
|
||||
assert(_d === "d");
|
||||
assert(_e === "e");
|
||||
assert(_f === "f");
|
||||
assert(_g === "g");
|
||||
}
|
||||
}
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; i++)
|
||||
foo(i % 2 ? o1 : o2);
|
||||
flag = true;
|
||||
foo(o1);
|
||||
@@ -0,0 +1,47 @@
|
||||
// @bun
|
||||
function foo(o, a) {
|
||||
let x = o.g;
|
||||
let y = o.y;
|
||||
try {
|
||||
o.f = 20;
|
||||
} catch(e) {
|
||||
return x + y + 1;
|
||||
}
|
||||
return x + y;
|
||||
}
|
||||
|
||||
function assert(b) {
|
||||
if (!b)
|
||||
throw new Error("bad value")
|
||||
}
|
||||
noInline(assert);
|
||||
|
||||
noInline(foo);
|
||||
var flag = false;
|
||||
function f(arg1, arg2, arg3) {
|
||||
if (flag)
|
||||
throw new Error("blah")
|
||||
return arg1;
|
||||
}
|
||||
noInline(f);
|
||||
let o1 = {
|
||||
g: 20,
|
||||
y: 40,
|
||||
f: null
|
||||
};
|
||||
|
||||
let o2 = {
|
||||
g: "g",
|
||||
y: "y",
|
||||
set f(v) { if (flag) throw new Error("blah"); }
|
||||
}
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
if (i % 2) {
|
||||
assert(foo(o1) === 60);
|
||||
} else {
|
||||
assert(foo(o2) === "gy");
|
||||
}
|
||||
}
|
||||
flag = true;
|
||||
assert(foo(o2) === "gy1");
|
||||
@@ -0,0 +1,33 @@
|
||||
// @bun
|
||||
function foo(o, a) {
|
||||
let resetFlag = false;
|
||||
if (flag) {
|
||||
resetFlag = true;
|
||||
flag = false;
|
||||
}
|
||||
let x = o(10);
|
||||
let y = o(20);
|
||||
if (resetFlag)
|
||||
flag = true;
|
||||
try {
|
||||
o.apply(null, a);
|
||||
} catch(e) {
|
||||
if (x !== 10)
|
||||
throw new Error("Not 10")
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
noInline(foo);
|
||||
var flag = false;
|
||||
function f(arg1, arg2, arg3) {
|
||||
if (flag)
|
||||
throw new Error("blah")
|
||||
return arg1;
|
||||
}
|
||||
noInline(f);
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
foo(f, [10, 20, 30]);
|
||||
}
|
||||
flag = true;
|
||||
foo(f, [10, 20, 30]);
|
||||
20
test/js/bun/jsc-stress/fixtures/ftl-xor-exception.js
Normal file
20
test/js/bun/jsc-stress/fixtures/ftl-xor-exception.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// @bun
|
||||
function foo(a, b) {
|
||||
try {
|
||||
return a ^ b;
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
var result = foo((i & 1) ? 32 : "32", 10);
|
||||
if (result !== 42)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
var result = foo({valueOf: function() { throw "error42"; }}, 10);
|
||||
if (result !== "error42")
|
||||
throw "Error: bad result at end: " + result;
|
||||
18
test/js/bun/jsc-stress/fixtures/licm-no-pre-header.js
Normal file
18
test/js/bun/jsc-stress/fixtures/licm-no-pre-header.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// @bun
|
||||
//@ runFTLNoCJIT("--createPreHeaders=false")
|
||||
|
||||
function foo(array) {
|
||||
var result = 0;
|
||||
var i = 0;
|
||||
if (!array.length)
|
||||
array = [1];
|
||||
do {
|
||||
result += array[i++];
|
||||
} while (i < array.length)
|
||||
return result;
|
||||
}
|
||||
|
||||
noInline(foo);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i)
|
||||
foo([1, 2, 3]);
|
||||
93
test/js/bun/jsc-stress/fixtures/loop-unrolling.js
Normal file
93
test/js/bun/jsc-stress/fixtures/loop-unrolling.js
Normal file
@@ -0,0 +1,93 @@
|
||||
// @bun
|
||||
function assert(actual, expected) {
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
if (actual[i] != expected[i])
|
||||
throw new Error("bad actual=" + actual[i] + " but expected=" + expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function func1(a) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
a[i] = 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func1);
|
||||
|
||||
function func2(a) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
a[i] = 1;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
a[i] = 1;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func2);
|
||||
|
||||
function func3(a) {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (i % 2 == 0)
|
||||
a[i] = 1;
|
||||
else
|
||||
a[i] = 2;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func3);
|
||||
|
||||
function func4(s) {
|
||||
let len = 4;
|
||||
var a = new Array(len);
|
||||
for (var i = 0; i < len; i++) {
|
||||
a[i] = s[i];
|
||||
}
|
||||
s[0] = a[0] ^ a[1];
|
||||
return s;
|
||||
}
|
||||
noInline(func4);
|
||||
|
||||
function func5(a) {
|
||||
for (let i = 0; i < 4;) {
|
||||
a[i] = 1;
|
||||
if (i > -1)
|
||||
i += 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func5);
|
||||
|
||||
function func6(a) {
|
||||
for (let i = 3; i > 1; i /= 2) {
|
||||
a[i] = 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func6);
|
||||
|
||||
function func7(a) {
|
||||
for (let i = 3; i < 4; i /= 0) {
|
||||
a[i] = 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
noInline(func7);
|
||||
|
||||
function test(func) {
|
||||
let expected;
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
let a = [0, 0, 0, 0];
|
||||
let res = func(a);
|
||||
if (i == 0)
|
||||
expected = res;
|
||||
assert(res, expected);
|
||||
}
|
||||
}
|
||||
|
||||
test(func1);
|
||||
test(func2);
|
||||
test(func3);
|
||||
test(func4);
|
||||
test(func5);
|
||||
test(func6);
|
||||
test(func7);
|
||||
@@ -0,0 +1,29 @@
|
||||
// @bun
|
||||
function foo(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
var global;
|
||||
function bar() {
|
||||
var a = arguments;
|
||||
var tmp = global + 1;
|
||||
return tmp + foo.apply(null, a);
|
||||
}
|
||||
|
||||
function baz(a, b) {
|
||||
return bar(a, b);
|
||||
}
|
||||
|
||||
noInline(baz);
|
||||
|
||||
for (var i = 0; i < testLoopCount; ++i) {
|
||||
global = i;
|
||||
var result = baz(1, 2);
|
||||
if (result != i + 1 + 1 + 2)
|
||||
throw "Error: bad result: " + result;
|
||||
}
|
||||
|
||||
global = 1.5;
|
||||
var result = baz(1, 2);
|
||||
if (result != 1.5 + 1 + 1 + 2)
|
||||
throw "Error: bad result at end: " + result;
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,141 @@
|
||||
// @bun
|
||||
function instantiate(moduleBase64, importObject) {
|
||||
let bytes = Uint8Array.fromBase64(moduleBase64);
|
||||
return WebAssembly.instantiate(bytes, importObject);
|
||||
}
|
||||
const report = $.agent.report;
|
||||
const isJIT = callerIsBBQOrOMGCompiled;
|
||||
const extra = {isJIT};
|
||||
(async function () {
|
||||
let memory0 = new WebAssembly.Memory({initial: 1850, shared: true, maximum: 2731});
|
||||
/**
|
||||
@param {I32} a0
|
||||
@param {F32} a1
|
||||
@returns {void}
|
||||
*/
|
||||
let fn0 = function (a0, a1) {
|
||||
a0?.toString(); a1?.toString();
|
||||
};
|
||||
/**
|
||||
@returns {void}
|
||||
*/
|
||||
let fn1 = function () {
|
||||
};
|
||||
/**
|
||||
@param {I32} a0
|
||||
@param {F32} a1
|
||||
@returns {[I32, F32]}
|
||||
*/
|
||||
let fn2 = function (a0, a1) {
|
||||
a0?.toString(); a1?.toString();
|
||||
return [36, 8.433544074882645e1];
|
||||
};
|
||||
/**
|
||||
@param {I32} a0
|
||||
@param {FuncRef} a1
|
||||
@returns {void}
|
||||
*/
|
||||
let fn3 = function (a0, a1) {
|
||||
a0?.toString(); a1?.toString();
|
||||
};
|
||||
let tag5 = new WebAssembly.Tag({parameters: []});
|
||||
let tag6 = new WebAssembly.Tag({parameters: ['i32', 'f32']});
|
||||
let tag9 = new WebAssembly.Tag({parameters: []});
|
||||
let global0 = new WebAssembly.Global({value: 'i32', mutable: true}, 3721432472);
|
||||
let global1 = new WebAssembly.Global({value: 'f64', mutable: true}, 548636.1280581957);
|
||||
let global3 = new WebAssembly.Global({value: 'f32', mutable: true}, 52810.0658290932);
|
||||
let global4 = new WebAssembly.Global({value: 'i64', mutable: true}, 1872919390n);
|
||||
let global7 = new WebAssembly.Global({value: 'anyfunc', mutable: true}, null);
|
||||
let global8 = new WebAssembly.Global({value: 'externref', mutable: true}, {});
|
||||
let table0 = new WebAssembly.Table({initial: 48, element: 'externref', maximum: 347});
|
||||
let table1 = new WebAssembly.Table({initial: 37, element: 'anyfunc'});
|
||||
let table2 = new WebAssembly.Table({initial: 51, element: 'externref', maximum: 276});
|
||||
let table3 = new WebAssembly.Table({initial: 77, element: 'externref'});
|
||||
let m2 = {fn3, global0, global2: global0, global7, memory0, tag5, tag6, tag9};
|
||||
let m1 = {fn0, fn1, fn2, global1, global6: global3, global8, table0, table1, table3, tag8: tag5, tag12: tag9};
|
||||
let m0 = {global3, global4, global5: global4, table2, table4: table3, tag7: tag5, tag10: tag9, tag11: tag6};
|
||||
let importObject0 = /** @type {Imports2} */ ({extra, m0, m1, m2});
|
||||
/*
|
||||
(func (;5;) (param ) (result )
|
||||
(local i32 i32)
|
||||
loop ;; label = @1
|
||||
local.get 1
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.tee 1
|
||||
i32.const 43
|
||||
i32.lt_u
|
||||
br_if 0 (;@1;)
|
||||
;; BEGIN IMPORTANT
|
||||
i32.const 1
|
||||
i32.const 6
|
||||
table.get 1
|
||||
;; BEGIN VERY IMPORTANT
|
||||
loop (param i32 funcref) (result i32 funcref) ;; label = @3
|
||||
try (param i32 funcref) (result i32 funcref) ;; label = @4
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.tee 0
|
||||
i32.const 36
|
||||
i32.lt_u
|
||||
if (param i32 funcref) (result i32 funcref) ;; label = @5
|
||||
br 2 (;@3;)
|
||||
end
|
||||
end
|
||||
end
|
||||
;; END VERY IMPORTANT
|
||||
table.set 1
|
||||
;; END IMPORTANT
|
||||
end
|
||||
)
|
||||
(func (;6;) (type 18) (param i32 f32)
|
||||
call 5
|
||||
return)
|
||||
|
||||
*/
|
||||
let i0 = await instantiate(
|
||||
'AGFzbQEAAAABgAETYAABf2ACf3AJcH1/cHt9f3t9YAJ/cAJ/cGACf3AAYANvcHsAYANvcHsDb3B7YANvcHsAYAN7fn8De317YAN7fn8De35/YAN7fn8AYANwfnsDfXB/YANwfnsDcH57YANwfnsAYAAAYAAAYAAAYAJ/fQJ7f2ACf30Cf31gAn99AALnAhwCbTIHbWVtb3J5MAIDug6rFQJtMQNmbjAAEgJtMQNmbjEADQJtMQNmbjIAEQJtMgNmbjMAAwVleHRyYQVpc0pJVAAAAm0yBHRhZzUEAA4CbTIEdGFnNgQAEgJtMAR0YWc3BAAPAm0xBHRhZzgEAA0CbTIEdGFnOQQADgJtMAV0YWcxMAQADwJtMAV0YWcxMQQAEgJtMQV0YWcxMgQADwJtMgdnbG9iYWwwA38BAm0xB2dsb2JhbDEDfAECbTIHZ2xvYmFsMgN/AQJtMAdnbG9iYWwzA30BAm0wB2dsb2JhbDQDfgECbTAHZ2xvYmFsNQN+AQJtMQdnbG9iYWw2A30BAm0yB2dsb2JhbDcDcAECbTEHZ2xvYmFsOANvAQJtMQZ0YWJsZTABbwEw2wICbTEGdGFibGUxAXAAJQJtMAZ0YWJsZTIBbwEzlAICbTEGdGFibGUzAW8ATQJtMAZ0YWJsZTQBbwA7AwMCDRIEFgVvAFhvARTTBm8BE6kGcABObwFNygYNFwsADwAOAAYADQAOAAwADQAJAA0ABgANBl4KfQFDC0JCjAt8AUTD6W+dAQahrQt+AULEAAt/AUHfAAt8AESAU9orGbwSsgt/AUEBC30BQ0MnTH8LfgFC7ZHWnwwLfwFBxwALewH9DIFrswgU3AOrzNvkUWHqRLwLB74BFQR0YWczBAcIZ2xvYmFsMTYDEgR0YWcwBAIDZm41AAYEdGFnMgQGBnRhYmxlOAEIBnRhYmxlNwEHB21lbW9yeTECAAhnbG9iYWwxNQMRBHRhZzEEBQNmbjQABQhnbG9iYWwxMQMKBHRhZzQECghnbG9iYWwxMAMJBnRhYmxlNgEGCGdsb2JhbDE0AxAGdGFibGU5AQkHZ2xvYmFsOQMACGdsb2JhbDEzAwwGdGFibGU1AQUIZ2xvYmFsMTIDCwnyAQkDAE4BBQEDAgUCAwAFAwEGBAQDAwIGBgEAAwADAQEFBAEBBQYFBgUBAwYEAgQABgACBQYFBAYEAAIBBQYGBQIFAgYGAQADBgAFAgEGAQUGBQUBAFQAAwUCAQIFBgYAAgAABQYEBAMDAgADAgEABgEBBAIAAQQCAAQGAQAFAQICAwUEAAYBAgAEAAYFBAYDAwUABgUGBgEAAQEAAAMFBAQBAgYGAwMGBgMCAUEUCwARAwIFAwYABQIAAwIGAwYCBQUCAUEeCwACAAYCCEEMCwABAQIIQSILAAECAghBEgsAAQMCCEELCwABBAIBQQELAAEFCjgCMAECfwNAIAFBAWoiAUErSQ0AQQFBBiUBAwIGAiAAQQFqIgBBJEkEAgwCCwsLJgELCwUAEAUPCwsZAwEHnzQg5BrOxgBBiscACwSuJgPYAQKQxA=='
|
||||
, importObject0);
|
||||
let {fn4, fn5, global9, global10, global11, global12, global13, global14, global15, global16, memory1, table5, table6, table7, table8, table9, tag0, tag1, tag2, tag3, tag4} = /**
|
||||
@type {{
|
||||
fn4: (a0: FuncRef, a1: I64, a2: V128) => [FuncRef, I64, V128],
|
||||
fn5: (a0: I32, a1: F32) => void,
|
||||
global9: WebAssembly.Global,
|
||||
global10: WebAssembly.Global,
|
||||
global11: WebAssembly.Global,
|
||||
global12: WebAssembly.Global,
|
||||
global13: WebAssembly.Global,
|
||||
global14: WebAssembly.Global,
|
||||
global15: WebAssembly.Global,
|
||||
global16: WebAssembly.Global,
|
||||
memory1: WebAssembly.Memory,
|
||||
table5: WebAssembly.Table,
|
||||
table6: WebAssembly.Table,
|
||||
table7: WebAssembly.Table,
|
||||
table8: WebAssembly.Table,
|
||||
table9: WebAssembly.Table,
|
||||
tag0: WebAssembly.Tag,
|
||||
tag1: WebAssembly.Tag,
|
||||
tag2: WebAssembly.Tag,
|
||||
tag3: WebAssembly.Tag,
|
||||
tag4: WebAssembly.Tag
|
||||
}} */ (i0.instance.exports);
|
||||
report('progress');
|
||||
try {
|
||||
for (let k=0; k<27; k++) {
|
||||
let zzz = fn5(global9.value, global3.value);
|
||||
if (zzz !== undefined) { throw new Error('expected undefined but return value is '+zzz); }
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof WebAssembly.Exception) {
|
||||
} else if (e instanceof TypeError) {
|
||||
if (e.message === 'an exported wasm function cannot contain a v128 parameter or return value') {} else { throw e; }
|
||||
} else if (e instanceof WebAssembly.RuntimeError || e instanceof RangeError) {} else { throw e; }
|
||||
}
|
||||
})().then(() => {
|
||||
report('after');
|
||||
}).catch(e => {
|
||||
report('error');
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
216
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try.js
Normal file
216
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,97 @@
|
||||
// @bun
|
||||
function instantiate(moduleBase64, importObject) {
|
||||
let bytes = Uint8Array.fromBase64(moduleBase64);
|
||||
return WebAssembly.instantiate(bytes, importObject);
|
||||
}
|
||||
const report = $.agent.report;
|
||||
const isJIT = callerIsBBQOrOMGCompiled;
|
||||
const extra = {isJIT};
|
||||
(async function () {
|
||||
let tag4 = new WebAssembly.Tag({parameters: ['i64', 'i64']});
|
||||
let global0 = new WebAssembly.Global({value: 'i64', mutable: true}, 3499732511n);
|
||||
let global1 = new WebAssembly.Global({value: 'anyfunc', mutable: true}, null);
|
||||
let global2 = new WebAssembly.Global({value: 'i32', mutable: true}, 2571545964);
|
||||
let global3 = new WebAssembly.Global({value: 'anyfunc', mutable: true}, global1.value);
|
||||
let global4 = new WebAssembly.Global({value: 'f32', mutable: true}, 364166.8042332507);
|
||||
let global7 = new WebAssembly.Global({value: 'f64', mutable: true}, 213733.71202709377);
|
||||
let global8 = new WebAssembly.Global({value: 'f32', mutable: true}, 616331.2736008756);
|
||||
let table0 = new WebAssembly.Table({initial: 0, element: 'externref'});
|
||||
let table1 = new WebAssembly.Table({initial: 9, element: 'anyfunc'});
|
||||
let table2 = new WebAssembly.Table({initial: 49, element: 'anyfunc'});
|
||||
let table3 = new WebAssembly.Table({initial: 26, element: 'externref', maximum: 430});
|
||||
let table4 = new WebAssembly.Table({initial: 28, element: 'externref'});
|
||||
let table5 = new WebAssembly.Table({initial: 49, element: 'externref', maximum: 474});
|
||||
let table6 = new WebAssembly.Table({initial: 15, element: 'anyfunc', maximum: 280});
|
||||
let m2 = {global3, global4, global5: global0, table0, table2, table4, tag4};
|
||||
let m1 = {global0, global1, global7, table6, tag5: tag4};
|
||||
let m0 = {global2, global6: 364324.50814459583, global8, table1, table3, table5};
|
||||
let importObject0 = /** @type {Imports2} */ ({extra, m0, m1, m2});
|
||||
let i0 = await instantiate('AGFzbQEAAAABXxBgAAF/YAJ+fgJve2ACfn4Cfn5gAn5+AGABcAh/fG97b31wcGABcAFwYAFwAGACcH4Db3x8YAJwfgJwfmACcH4AYAF7AGABewF7YAF7AGACfnsAYAJ+ewJ+e2ACfnsAAosCEwVleHRyYQVpc0pJVAAAAm0yBHRhZzQEAAMCbTEEdGFnNQQAAwJtMQdnbG9iYWwwA34BAm0xB2dsb2JhbDEDcAECbTAHZ2xvYmFsMgN/AQJtMgdnbG9iYWwzA3ABAm0yB2dsb2JhbDQDfQECbTIHZ2xvYmFsNQN+AQJtMAdnbG9iYWw2A30AAm0xB2dsb2JhbDcDfAECbTAHZ2xvYmFsOAN9AQJtMgZ0YWJsZTABbwAAAm0wBnRhYmxlMQFwAAkCbTIGdGFibGUyAXAAMQJtMAZ0YWJsZTMBbwEargMCbTIGdGFibGU0AW8AHAJtMAZ0YWJsZTUBbwEx2gMCbTEGdGFibGU2AXABD5gCAwMCDwIEBgFwAT2wBAUGAQPSCYMQDRcLAAwACQAGAAkACQAJAAwADAANAA0ABgaFAQx7Af0MSvvsAkF//41/ksqiwFUESgtwAdICC3wBRMl1001ATPf/C28B0G8LcAHSAgtwAdIAC3sB/QwH9MyIphr6KdyXprh7fPloC34BQrzhuODeegt/AEHCAAt8AURT14ly27r68gt7AP0M1TBKHFqzCmT7EI53D27/cAt/AUHM7MzGAQsHtQETBnRhYmxlOQEHCGdsb2JhbDE3AxEHZ2xvYmFsOQMECGdsb2JhbDE0Aw4IZ2xvYmFsMTgDEghnbG9iYWwxNgMQCGdsb2JhbDE1Aw8IZ2xvYmFsMTADCgR0YWcxBAcIZ2xvYmFsMTEDCwNmbjAAAghnbG9iYWwxMwMNB21lbW9yeTACAAhnbG9iYWwxMgMMBnRhYmxlOAEEBHRhZzIECAZ0YWJsZTcBAQR0YWczBAkEdGFnMAQFCT4FAgFBAAsACQAAAAEAAAABAAMAEgICAAEAAAACAgABAQICAAACAAICQQoLAAEAAgZBBQsAAQECBkENCwABAgwBBwrvCwLuAg0BfwF/AH0AfwJ8AX8AfwB+AHsDfwF+AX0BfBAAQQJwBH8gBdIAPwAiA2m+BnDSAf0MW4f6DJC9VBevMYa1Q9gAWQYLJAkjDv0MLtXzSgKr6pLdIoiLAptqrQYKBgwGCwYLPwBBAnAECgwBAAUhASMODAYAC0P1NwSnJAQMAgsMAAsMAgsHCCIB/XUMAQsMAQsGDELjl4ebon4kEAJwDwALQxLBENQkCCQBAnsMBAALQfyGkQRBAnAOAgADAwtCqwEgAURiitQ26hFukL39HgH9Xz8ADAELA28Gf0Ho1fQADAALQQFwDgECAgv9DM0AI7omeJ5QG76lo8Devt/9+gECDCQJ/BAGDAEACyQM/BAHDAAFDwALQQJwBH4CAAZ9RGTXHfsvfcPaQgm1/BACDAELQbkBQQFwDgECAgALBAAPAAVE8R4bfJtM+X8kEgJADwALAAsaQQAOAQEBBSMEJAhB6DEOAQEBC6cOAQAAC/wICwJ7AH4AfQF+AHsCewJwA38BfgF9AXwjEFACfSABAnsjEP0MzJzUMHwQSzAr5Y6yYfR2ZhAB0gJDz+qgPiABBkAGACMMQgN5BkAGbxAADAIAC/wQAwwBC1AOAQEBC0EBcA4BAAALQZgBQQJwBH0gCAIEAwQGBRAARQQFDAILAkAMAAALDAALIA1DAACAP5IiDUMAADRCXQQFDAELQQ1BAnAEBiEHDAAABfwQBkECcAQGIApBAWoiCkEvSQQFDAMLJA4MAAAFIApBAWoiCkEGSQQFDAMLAgX9DLeK2iUOJnZ0H0sQF7mKpA4GCiECIAgMAQsMAAsGBCQNIwj8BMTSAiAIAgYkAQwDAAsGfUGlms8IQuoAtQwAAAsMBwALAwY/AA0BIxH9DwIMQrsBIQECCgwIAAsACwALIQf8EAFBAnAOAgABAQsQAEEBcA4BAAALAnwDQEErQQBBAPwMAQIgCUEBaiIJQSNJBEAMAQtCyuyxqMLklVkCftIBIwYMBwALAAsACwALAAsABQMABgBEYWVk/1wWMcBENT9BSSE39H/SAUTuDhdNc7nY2kKKpgMhBCMLQeMA0gIjDdIC0gH8EAUMAAsCfhAAQcwBtyQLaCQCBgAgC0EBaiILQSBJDQJD3NKWiwwDC0ECcAR+QxxVF3zSABoMBQAFIwucQeQBRHs2YwqKIiSkJAf8EANwJQNEk8Hh1rhmAmf8AyAIAm8CACAMQgF8IgxCC1QNBBAABH0GAAZ7IAlBAWoiCUExSQRADAgLBgAjFPwQBgRwPwAEfdIBGiAKQQFqIgpBIEkEQAwLCwIAIwIkAiAORAAAAAAAAPA/oCIORAAAAAAAADtAYwRADAwLIA5EAAAAAAAA8D+gIg5EAAAAAAAAOkBjBEAMDAtBPQsMBgAFBkALIwbSAhrSAANACxoMAAALDAQABQYABntBEkEAQQD8DAMC/Qxz1pWCgqN4QjkH9cI49JPYDAQLDAwLDAEAC0HN7t4ADAALQQJwBH9B3w8MAAAFIA1DAACAP5IiDUMAAMhBXQ0IIApBAWoiCkEeSQ0IQacMC0EHDAML0gEGfQYAAnwQAAwDAAskC0HnAQwEC/0MxHNbhlXK8zjfKA3h8+FEHgwJAQAL/BAFDAIZIAxCAXwiDEIwVA0GIAtBAWoiC0EGSQ0GIAUMCAsMAQUGbwJ9Q+4ZI74MAgALjT8ADAILDAILDAULswwGCyQMJA78EAZwIw4mBtICGtIBGv0MYt/qQomva73WBylo196mAAIMDAUACwALCyQQCyQUIwYLDAELBnv9DDEidditCJ8vf4uYIk2MFmcL/cABIQYkDyQFQ0G4APsL/RMkCSQUIwAjEAMBDwALIQUkDAYARE7RvAAAHcfhJAtBHQskFCAE/RL9wQEGCtIBGkLzAP0MGNPW59bqb0fD7+9K3USBjRqnJBQCfwwBAAtBAnAECiQPDAEABQYKJA8CAAwCAAtBA3AOAwACAQELCwtDQCqZVyQEQuivmM/Kz5vFAEKOzIrv/Y+tcgsLUQcBCblMexqkzpD0oAIAQZPwAQsImxRxEVil3JgAQY3/AAsF1ZqzNeEAQeDQAAsHeJPHtN0SMQEFRv6yBRgAQYqqAgsGgqDibfNEAgBBsyILAA==', importObject0);
|
||||
let {fn0, global9, global10, global11, global12, global13, global14, global15, global16, global17, global18, memory0, table7, table8, table9, tag0, tag1, tag2, tag3} = /**
|
||||
@type {{
|
||||
fn0: (a0: I64, a1: I64) => [I64, I64],
|
||||
global9: WebAssembly.Global,
|
||||
global10: WebAssembly.Global,
|
||||
global11: WebAssembly.Global,
|
||||
global12: WebAssembly.Global,
|
||||
global13: WebAssembly.Global,
|
||||
global14: WebAssembly.Global,
|
||||
global15: WebAssembly.Global,
|
||||
global16: WebAssembly.Global,
|
||||
global17: WebAssembly.Global,
|
||||
global18: WebAssembly.Global,
|
||||
memory0: WebAssembly.Memory,
|
||||
table7: WebAssembly.Table,
|
||||
table8: WebAssembly.Table,
|
||||
table9: WebAssembly.Table,
|
||||
tag0: WebAssembly.Tag,
|
||||
tag1: WebAssembly.Tag,
|
||||
tag2: WebAssembly.Tag,
|
||||
tag3: WebAssembly.Tag
|
||||
}} */ (i0.instance.exports);
|
||||
table3.set(6, table0);
|
||||
table8.set(24, table3);
|
||||
table8.set(11, table3);
|
||||
table5.set(46, table8);
|
||||
table3.set(5, table8);
|
||||
global16.value = 0n;
|
||||
global1.value = null;
|
||||
report('progress');
|
||||
try {
|
||||
for (let k=0; k<29; k++) {
|
||||
let zzz = fn0(global0.value, global16.value);
|
||||
if (!(zzz instanceof Array)) { throw new Error('expected array but return value is '+zzz); }
|
||||
if (zzz.length != 2) { throw new Error('expected array of length 2 but return value is '+zzz); }
|
||||
let [r0, r1] = zzz;
|
||||
r0?.toString(); r1?.toString();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof WebAssembly.Exception) {
|
||||
} else if (e instanceof TypeError) {
|
||||
if (e.message === 'an exported wasm function cannot contain a v128 parameter or return value') {} else { throw e; }
|
||||
} else if (e instanceof WebAssembly.RuntimeError || e instanceof RangeError) {} else { throw e; }
|
||||
}
|
||||
report('progress');
|
||||
try {
|
||||
for (let k=0; k<27; k++) {
|
||||
let zzz = fn0(global0.value, global16.value);
|
||||
if (!(zzz instanceof Array)) { throw new Error('expected array but return value is '+zzz); }
|
||||
if (zzz.length != 2) { throw new Error('expected array of length 2 but return value is '+zzz); }
|
||||
let [r0, r1] = zzz;
|
||||
r0?.toString(); r1?.toString();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof WebAssembly.Exception) {
|
||||
} else if (e instanceof TypeError) {
|
||||
if (e.message === 'an exported wasm function cannot contain a v128 parameter or return value') {} else { throw e; }
|
||||
} else if (e instanceof WebAssembly.RuntimeError || e instanceof RangeError) {} else { throw e; }
|
||||
}
|
||||
let tables = [table0, table4, table3, table5, table8, table1, table2, table6, table9, table7];
|
||||
for (let table of tables) {
|
||||
for (let k=0; k < table.length; k++) { table.get(k)?.toString(); }
|
||||
}
|
||||
})().then(() => {
|
||||
report('after');
|
||||
}).catch(e => {
|
||||
report('error');
|
||||
})
|
||||
163
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try3.js
Normal file
163
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try3.js
Normal file
File diff suppressed because one or more lines are too long
142
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try4.js
Normal file
142
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try4.js
Normal file
File diff suppressed because one or more lines are too long
162
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try5.js
Normal file
162
test/js/bun/jsc-stress/fixtures/wasm/ipint-bbq-osr-with-try5.js
Normal file
File diff suppressed because one or more lines are too long
114
test/js/bun/jsc-stress/fixtures/wasm/omg-osr-stack-check-2.js
Normal file
114
test/js/bun/jsc-stress/fixtures/wasm/omg-osr-stack-check-2.js
Normal file
@@ -0,0 +1,114 @@
|
||||
// @bun
|
||||
//@ runDefaultWasm("--jitPolicyScale=0", "--useConcurrentJIT=0")
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
async function instantiate(filename, importObject) {
|
||||
const bytes = fs.readFileSync(path.join(import.meta.dirname, filename));
|
||||
return WebAssembly.instantiate(bytes, importObject);
|
||||
}
|
||||
const log = function () {};
|
||||
const report = function () {};
|
||||
const isJIT = callerIsBBQOrOMGCompiled;
|
||||
const extra = { isJIT };
|
||||
(async function () {
|
||||
let memory0 = new WebAssembly.Memory({ initial: 3947, shared: false, maximum: 6209 });
|
||||
let tag3 = new WebAssembly.Tag({ parameters: [] });
|
||||
let global0 = new WebAssembly.Global({ value: "f64", mutable: true }, 882640.3220068762);
|
||||
let global1 = new WebAssembly.Global({ value: "f32", mutable: true }, 162294.89036678328);
|
||||
let global2 = new WebAssembly.Global({ value: "f64", mutable: true }, 50173.96827009934);
|
||||
let table0 = new WebAssembly.Table({ initial: 6, element: "externref" });
|
||||
let m1 = { global0, memory0, tag3 };
|
||||
let m0 = { global1, global2 };
|
||||
let m2 = { table0 };
|
||||
let importObject0 = /** @type {Imports2} */ ({ m0, m1, m2 });
|
||||
let i0 = await instantiate("omg-osr-stack-check-2.wasm", importObject0);
|
||||
let { fn0, global3, global4, memory1, table1, table2, table3, table4, table5, table6, table7, tag0, tag1, tag2 } = /**
|
||||
@type {{
|
||||
fn0: () => void,
|
||||
global3: WebAssembly.Global,
|
||||
global4: WebAssembly.Global,
|
||||
memory1: WebAssembly.Memory,
|
||||
table1: WebAssembly.Table,
|
||||
table2: WebAssembly.Table,
|
||||
table3: WebAssembly.Table,
|
||||
table4: WebAssembly.Table,
|
||||
table5: WebAssembly.Table,
|
||||
table6: WebAssembly.Table,
|
||||
table7: WebAssembly.Table,
|
||||
tag0: WebAssembly.Tag,
|
||||
tag1: WebAssembly.Tag,
|
||||
tag2: WebAssembly.Tag
|
||||
}} */ (i0.instance.exports);
|
||||
table4.set(6, table7);
|
||||
table4.set(44, table1);
|
||||
global4.value = 0;
|
||||
log("calling fn0");
|
||||
report("progress");
|
||||
try {
|
||||
for (let k = 0; k < 21; k++) {
|
||||
let zzz = fn0();
|
||||
if (zzz !== undefined) {
|
||||
throw new Error("expected undefined but return value is " + zzz);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof WebAssembly.Exception) {
|
||||
log(e);
|
||||
if (e.stack) {
|
||||
log(e.stack);
|
||||
}
|
||||
} else if (e instanceof TypeError) {
|
||||
if (e.message === "an exported wasm function cannot contain a v128 parameter or return value") {
|
||||
log(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} else if (e instanceof WebAssembly.RuntimeError || e instanceof RangeError) {
|
||||
log(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
log("calling fn0");
|
||||
report("progress");
|
||||
try {
|
||||
for (let k = 0; k < 19; k++) {
|
||||
let zzz = fn0();
|
||||
if (zzz !== undefined) {
|
||||
throw new Error("expected undefined but return value is " + zzz);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof WebAssembly.Exception) {
|
||||
log(e);
|
||||
if (e.stack) {
|
||||
log(e.stack);
|
||||
}
|
||||
} else if (e instanceof TypeError) {
|
||||
if (e.message === "an exported wasm function cannot contain a v128 parameter or return value") {
|
||||
log(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} else if (e instanceof WebAssembly.RuntimeError || e instanceof RangeError) {
|
||||
log(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
let tables = [table0, table7, table5, table1, table4, table3, table6, table2];
|
||||
for (let table of tables) {
|
||||
for (let k = 0; k < table.length; k++) {
|
||||
table.get(k)?.toString();
|
||||
}
|
||||
}
|
||||
})()
|
||||
.then(() => {
|
||||
log("after");
|
||||
report("after");
|
||||
})
|
||||
.catch(e => {
|
||||
log(e);
|
||||
log("error");
|
||||
report("error");
|
||||
});
|
||||
BIN
test/js/bun/jsc-stress/fixtures/wasm/omg-osr-stack-check-2.wasm
Normal file
BIN
test/js/bun/jsc-stress/fixtures/wasm/omg-osr-stack-check-2.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,35 @@
|
||||
// @bun
|
||||
//@ skip if $architecture == "arm"
|
||||
//@ runDefault("--jitPolicyScale=0")
|
||||
const v39 = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
|
||||
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x23,
|
||||
0x03, 0x60, 0x00, 0x00, 0x60, 0x09, 0x7E, 0x63, 0x6C, 0x7E,
|
||||
0x7F, 0x63, 0x6F, 0x7E, 0x63, 0x71, 0x63, 0x6F, 0x7E, 0x03,
|
||||
0x7E, 0x63, 0x71, 0x63, 0x72, 0x60, 0x01, 0x63, 0x6C, 0x03,
|
||||
0x7E, 0x63, 0x71, 0x63, 0x72, 0x03, 0x03, 0x02, 0x01, 0x02,
|
||||
0x04, 0x05, 0x01, 0x63, 0x70, 0x00, 0x0A, 0x05, 0x01, 0x00,
|
||||
0x06, 0x01, 0x00, 0x07, 0x11, 0x03, 0x02, 0x77, 0x30, 0x00,
|
||||
0x00, 0x02, 0x77, 0x31, 0x00, 0x01, 0x03, 0x77, 0x74, 0x30,
|
||||
0x01, 0x00, 0x09, 0x09, 0x01, 0x02, 0x00, 0x41, 0x00, 0x0B,
|
||||
0x00, 0x01, 0x00, 0x00, 0x20, 0x19, 0x6D, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2E, 0x63, 0x6F, 0x64, 0x65, 0x2E,
|
||||
0x62, 0x72, 0x61, 0x6E, 0x63, 0x68, 0x5F, 0x68, 0x69, 0x6E,
|
||||
0x74, 0x01, 0x01, 0x01, 0x30, 0x01, 0x01, 0x0A, 0x92, 0x01,
|
||||
0x02, 0x1D, 0x03, 0x01, 0x7B, 0x01, 0x7E, 0x01, 0x63, 0x72,
|
||||
0x20, 0x00, 0xFD, 0x12, 0x21, 0x09, 0x42, 0x07, 0x21, 0x0A,
|
||||
0xD0, 0x72, 0x21, 0x0B, 0x20, 0x0A, 0x20, 0x06, 0x20, 0x0B,
|
||||
0x0B, 0x72, 0x0A, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
|
||||
0x7F, 0x01, 0x63, 0x72, 0x01, 0x63, 0x71, 0x01, 0x7E, 0x01,
|
||||
0x7E, 0x01, 0x7E, 0x01, 0x7F, 0x41, 0x94, 0xFD, 0x01, 0x21,
|
||||
0x01, 0x03, 0x00, 0x41, 0x01, 0x21, 0x02, 0x20, 0x01, 0x20,
|
||||
0x02, 0x6B, 0x21, 0x03, 0x20, 0x03, 0x21, 0x01, 0x20, 0x01,
|
||||
0x0D, 0x00, 0x0B, 0x41, 0x00, 0x21, 0x04, 0xD0, 0x72, 0x21,
|
||||
0x05, 0xD0, 0x71, 0x21, 0x06, 0x42, 0xFF, 0x00, 0x21, 0x07,
|
||||
0x42, 0xE7, 0xFF, 0xFF, 0xFF, 0x01, 0x21, 0x08, 0x42, 0x09,
|
||||
0x21, 0x09, 0x41, 0x00, 0x21, 0x0A, 0x20, 0x09, 0x20, 0x00,
|
||||
0x20, 0x08, 0x20, 0x04, 0x20, 0x05, 0x20, 0x07, 0x20, 0x06,
|
||||
0x20, 0x05, 0x20, 0x08, 0x20, 0x0A, 0x13, 0x01, 0x00, 0x20,
|
||||
0x09, 0x20, 0x06, 0x20, 0x05, 0x0B,
|
||||
])));
|
||||
// Don't crash.
|
||||
v39.exports.w1(-900879769);
|
||||
@@ -0,0 +1,9 @@
|
||||
// @bun
|
||||
//@ runDefaultWasm("--jitPolicyScale=0", "--useConcurrentJIT=0")
|
||||
var wasm_code = new Uint8Array([
|
||||
0x00,0x61,0x73,0x6d,0x01,0x00,0x00,0x00,0x01,0xa7,0x80,0x80,0x80,0x00,0x03,0x60,0x02,0x7f,0x7f,0x01,0x7f,0x60,0x00,0x00,0x60,0x1a,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00,0x03,0x84,0x80,0x80,0x80,0x00,0x03,0x00,0x02,0x01,0x04,0x85,0x80,0x80,0x80,0x00,0x01,0x70,0x01,0x01,0x01,0x05,0x84,0x80,0x80,0x80,0x00,0x01,0x01,0x01,0x01,0x07,0x88,0x80,0x80,0x80,0x00,0x01,0x04,0x6d,0x61,0x69,0x6e,0x00,0x00,0x09,0x89,0x80,0x80,0x80,0x00,0x01,0x04,0x41,0x00,0x0b,0x01,0xd2,0x02,0x0b,0x0a,0x92,0x82,0x80,0x80,0x00,0x03,0xf9,0x81,0x80,0x80,0x00,0x00,0x03,0x40,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x43,0xb4,0xa2,0x91,0x4d,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x42,0xef,0x9b,0xaf,0xcd,0xf8,0xac,0xd1,0x91,0x01,0x10,0x01,0x20,0x00,0x41,0x01,0x6b,0x22,0x00,0x0d,0x00,0x0b,0x41,0x00,0x0b,0x87,0x80,0x80,0x80,0x00,0x00,0x41,0x00,0x13,0x01,0x00,0x0b,0x82,0x80,0x80,0x80,0x00,0x00,0x0b,
|
||||
]);
|
||||
var wasm_module = new WebAssembly.Module(wasm_code);
|
||||
var wasm_instance = new WebAssembly.Instance(wasm_module);
|
||||
var f = wasm_instance.exports.main;
|
||||
f(100000);
|
||||
@@ -0,0 +1,152 @@
|
||||
// @bun
|
||||
/*
|
||||
(module
|
||||
(tag $nonzero (param))
|
||||
(tag $zero (param))
|
||||
|
||||
(type $i32-i32 (func (param i32) (result i32)))
|
||||
(table $countdown-table funcref (elem $countdown-indirect))
|
||||
|
||||
(func $countdown (param i32) (result i32) (local f32)
|
||||
f32.const 42
|
||||
local.set 1
|
||||
|
||||
try
|
||||
local.get 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
if
|
||||
throw $zero
|
||||
else
|
||||
throw $nonzero
|
||||
end
|
||||
catch $nonzero
|
||||
local.get 0
|
||||
local.get 0
|
||||
i32.add
|
||||
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
return_call $countdown
|
||||
catch_all
|
||||
end
|
||||
|
||||
f32.const 0
|
||||
local.get 1
|
||||
f32.add
|
||||
i32.trunc_f32_u
|
||||
)
|
||||
|
||||
(func $countdown-indirect (param i32) (result i32) (local f32)
|
||||
f32.const 42
|
||||
local.set 1
|
||||
|
||||
try
|
||||
local.get 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
if
|
||||
throw $zero
|
||||
else
|
||||
throw $nonzero
|
||||
end
|
||||
catch $nonzero
|
||||
local.get 0
|
||||
local.get 0
|
||||
i32.add
|
||||
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
i32.const 0
|
||||
return_call_indirect $countdown-table (type $i32-i32)
|
||||
catch_all
|
||||
end
|
||||
|
||||
f32.const 0
|
||||
local.get 1
|
||||
f32.add
|
||||
i32.trunc_f32_u
|
||||
)
|
||||
|
||||
(func $countdown-ref (param i32) (result i32) (local f32)
|
||||
f32.const 42
|
||||
local.set 1
|
||||
|
||||
try
|
||||
local.get 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
if
|
||||
throw $zero
|
||||
else
|
||||
throw $nonzero
|
||||
end
|
||||
catch $nonzero
|
||||
local.get 0
|
||||
local.get 0
|
||||
i32.add
|
||||
|
||||
local.get 0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
ref.func $countdown-ref
|
||||
return_call_ref $i32-i32
|
||||
catch_all
|
||||
end
|
||||
|
||||
f32.const 0
|
||||
local.get 1
|
||||
f32.add
|
||||
i32.trunc_f32_u
|
||||
)
|
||||
|
||||
(func (export "main")
|
||||
block
|
||||
block
|
||||
i32.const 100000
|
||||
call $countdown
|
||||
i32.const 42
|
||||
i32.eq
|
||||
br_if 0
|
||||
unreachable
|
||||
end
|
||||
i32.const 100000
|
||||
call $countdown-indirect
|
||||
i32.const 42
|
||||
i32.eq
|
||||
br_if 0
|
||||
unreachable
|
||||
end
|
||||
i32.const 100000
|
||||
call $countdown-ref
|
||||
i32.const 42
|
||||
i32.eq
|
||||
br_if 0
|
||||
unreachable
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
var code = new Uint8Array([
|
||||
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x09, 0x02, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x00,
|
||||
0x03, 0x05, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x0d, 0x05, 0x02, 0x00, 0x01,
|
||||
0x00, 0x01, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x03, 0x09, 0x0b, 0x02, 0x00, 0x41, 0x00, 0x0b,
|
||||
0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x0a, 0xdb, 0x01, 0x04, 0x36, 0x01, 0x01, 0x7d, 0x43, 0x00, 0x00, 0x28, 0x42,
|
||||
0x21, 0x01, 0x06, 0x40, 0x20, 0x00, 0x41, 0x00, 0x46, 0x04, 0x40, 0x08, 0x01, 0x05, 0x08, 0x00, 0x0b, 0x00, 0x07,
|
||||
0x00, 0x20, 0x00, 0x20, 0x00, 0x6a, 0x1a, 0x20, 0x00, 0x41, 0x01, 0x6b, 0x12, 0x00, 0x19, 0x01, 0x0b, 0x43, 0x00,
|
||||
0x00, 0x00, 0x00, 0x20, 0x01, 0x92, 0xa9, 0x0b, 0x39, 0x01, 0x01, 0x7d, 0x43, 0x00, 0x00, 0x28, 0x42, 0x21, 0x01,
|
||||
0x06, 0x40, 0x20, 0x00, 0x41, 0x00, 0x46, 0x04, 0x40, 0x08, 0x01, 0x05, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x20,
|
||||
0x00, 0x20, 0x00, 0x6a, 0x1a, 0x20, 0x00, 0x41, 0x01, 0x6b, 0x41, 0x00, 0x13, 0x00, 0x00, 0x19, 0x01, 0x0b, 0x43,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x92, 0xa9, 0x0b, 0x38, 0x01, 0x01, 0x7d, 0x43, 0x00, 0x00, 0x28, 0x42, 0x21,
|
||||
0x01, 0x06, 0x40, 0x20, 0x00, 0x41, 0x00, 0x46, 0x04, 0x40, 0x08, 0x01, 0x05, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00,
|
||||
0x20, 0x00, 0x20, 0x00, 0x6a, 0x1a, 0x20, 0x00, 0x41, 0x01, 0x6b, 0xd2, 0x02, 0x15, 0x00, 0x19, 0x01, 0x0b, 0x43,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x92, 0xa9, 0x0b, 0x2f, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x41, 0xa0,
|
||||
0x8d, 0x06, 0x10, 0x00, 0x41, 0x2a, 0x46, 0x0d, 0x00, 0x00, 0x0b, 0x41, 0xa0, 0x8d, 0x06, 0x10, 0x01, 0x41, 0x2a,
|
||||
0x46, 0x0d, 0x00, 0x00, 0x0b, 0x41, 0xa0, 0x8d, 0x06, 0x10, 0x02, 0x41, 0x2a, 0x46, 0x0d, 0x00, 0x00, 0x0b, 0x0b
|
||||
]);
|
||||
|
||||
var module = new WebAssembly.Module(code);
|
||||
var instance = new WebAssembly.Instance(module);
|
||||
instance.exports.main()
|
||||
@@ -0,0 +1,44 @@
|
||||
// @bun
|
||||
/*
|
||||
(module
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(import "env" "getOffset" (func $getOffset (result i32 i32)))
|
||||
|
||||
(func (export "load") (result i32)
|
||||
(call $getOffset)
|
||||
(drop)
|
||||
(i32.load)
|
||||
)
|
||||
)
|
||||
*/
|
||||
const WASM_MODULE_CODE = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x02, 0x60, 0x00, 0x02, 0x7f, 0x7f, 0x60, 0x00, 0x01, 0x7f, 0x02, 0x20, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x01, 0x01, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x67, 0x65, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x07, 0x08, 0x01, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x00, 0x01, 0x0a, 0x0a, 0x01, 0x08, 0x00, 0x10, 0x00, 0x1a, 0x28, 0x02, 0x00, 0x0b, 0x00, 0x13, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x0c, 0x01, 0x00, 0x09, 0x67, 0x65, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74]);
|
||||
|
||||
function main() {
|
||||
const module = new WebAssembly.Module(WASM_MODULE_CODE);
|
||||
|
||||
const memory = new WebAssembly.Memory({
|
||||
initial: 1,
|
||||
maximum: 1
|
||||
});
|
||||
|
||||
const instance = new WebAssembly.Instance(module, {
|
||||
env: {
|
||||
memory,
|
||||
getOffset: () => [-0x80000000, 1]
|
||||
}
|
||||
});
|
||||
|
||||
for (let i = 0; i < testLoopCount; i++) {
|
||||
try {
|
||||
// Should throw an exception
|
||||
const value = instance.exports.load();
|
||||
|
||||
print(value);
|
||||
return;
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
202
test/js/bun/jsc-stress/jsc-stress.test.ts
Normal file
202
test/js/bun/jsc-stress/jsc-stress.test.ts
Normal file
@@ -0,0 +1,202 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import fs from "fs";
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
import path from "path";
|
||||
|
||||
const fixturesDir = path.join(import.meta.dir, "fixtures");
|
||||
const wasmFixturesDir = path.join(fixturesDir, "wasm");
|
||||
|
||||
/**
|
||||
* Parse JSC option flags from //@ directives at the top of a test file.
|
||||
* Converts --flag=value to BUN_JSC_flag=value environment variables.
|
||||
*
|
||||
* Supported directives:
|
||||
* //@ runDefault("--flag=value", ...)
|
||||
* //@ runFTLNoCJIT("--flag=value", ...)
|
||||
* //@ runDefaultWasm("--flag=value", ...)
|
||||
*/
|
||||
function parseJSCFlags(filePath: string): Record<string, string> {
|
||||
const content = fs.readFileSync(filePath, "utf-8");
|
||||
const env: Record<string, string> = {};
|
||||
|
||||
for (const line of content.split("\n")) {
|
||||
if (line === "// @bun" || line.trim() === "") continue;
|
||||
if (!line.startsWith("//@")) break;
|
||||
|
||||
const match = line.match(/^\/\/@ (runDefault|runFTLNoCJIT|runDefaultWasm)\((.*)\)/);
|
||||
if (!match) continue;
|
||||
|
||||
const [, mode, argsStr] = match;
|
||||
|
||||
// runFTLNoCJIT implies these flags (from WebKit's run-jsc-stress-tests)
|
||||
if (mode === "runFTLNoCJIT") {
|
||||
env["BUN_JSC_useFTLJIT"] = "true";
|
||||
env["BUN_JSC_useConcurrentJIT"] = "false";
|
||||
}
|
||||
|
||||
// Parse explicit flags: "--key=value"
|
||||
const flagPattern = /"--(\w+)=([^"]+)"/g;
|
||||
let flagMatch;
|
||||
while ((flagMatch = flagPattern.exec(argsStr)) !== null) {
|
||||
env[`BUN_JSC_${flagMatch[1]}`] = flagMatch[2];
|
||||
}
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
const jsFixtures = [
|
||||
// FTL - Math intrinsics
|
||||
"ftl-arithsin.js",
|
||||
"ftl-arithcos.js",
|
||||
"ftl-arithsqrt.js",
|
||||
"ftl-arithtan.js",
|
||||
// FTL - String ops
|
||||
"ftl-string-equality.js",
|
||||
"ftl-string-strict-equality.js",
|
||||
"ftl-string-ident-equality.js",
|
||||
"ftl-library-substring.js",
|
||||
// FTL - RegExp
|
||||
"ftl-regexp-exec.js",
|
||||
"ftl-regexp-test.js",
|
||||
// FTL - Arguments
|
||||
"ftl-getmyargumentslength.js",
|
||||
"ftl-getmyargumentslength-inline.js",
|
||||
"ftl-get-my-argument-by-val.js",
|
||||
"ftl-get-my-argument-by-val-inlined.js",
|
||||
"ftl-get-my-argument-by-val-inlined-and-not-inlined.js",
|
||||
// FTL - Exceptions
|
||||
"ftl-call-exception.js",
|
||||
"ftl-call-exception-no-catch.js",
|
||||
"ftl-call-varargs-exception.js",
|
||||
"ftl-try-catch-arith-sub-exception.js",
|
||||
"ftl-try-catch-getter-throw.js",
|
||||
"ftl-try-catch-setter-throw.js",
|
||||
"ftl-try-catch-patchpoint-with-volatile-registers.js",
|
||||
"ftl-try-catch-varargs-call-throws.js",
|
||||
"ftl-try-catch-getter-throw-interesting-value-recovery.js",
|
||||
"ftl-get-by-id-getter-exception.js",
|
||||
"ftl-get-by-id-slow-exception.js",
|
||||
"ftl-put-by-id-setter-exception.js",
|
||||
"ftl-put-by-id-slow-exception.js",
|
||||
"ftl-operation-exception.js",
|
||||
"ftl-shr-exception.js",
|
||||
"ftl-sub-exception.js",
|
||||
"ftl-xor-exception.js",
|
||||
// FTL - Property access
|
||||
"ftl-reallocatepropertystorage.js",
|
||||
"ftl-checkin.js",
|
||||
"ftl-checkin-variable.js",
|
||||
// FTL - OSR / Numeric / Misc
|
||||
"ftl-force-osr-exit.js",
|
||||
"ftl-negate-zero.js",
|
||||
"ftl-has-a-bad-time.js",
|
||||
"ftl-materialize-new-array-buffer.js",
|
||||
"ftl-tail-call.js",
|
||||
"ftl-library-inlining-random.js",
|
||||
"ftl-library-inlining-loops.js",
|
||||
"ftl-new-negative-array-size.js",
|
||||
"ftl-in-overflow.js",
|
||||
// DFG
|
||||
"dfg-ssa-swap.js",
|
||||
"dfg-to-primitive-pass-symbol.js",
|
||||
"dfg-strength-reduction-on-mod-should-handle-INT_MIN.js",
|
||||
"dfg-put-by-val-direct-with-edge-numbers.js",
|
||||
"dfg-create-arguments-inline-alloc.js",
|
||||
"dfg-internal-function-call.js",
|
||||
"dfg-internal-function-construct.js",
|
||||
"dfg-rare-data.js",
|
||||
"dfg-ai-fold-bigint.js",
|
||||
"dfg-node-convert-to-constant-must-clear-varargs-flags.js",
|
||||
"dfg-try-catch-wrong-value-recovery-on-ic-miss.js",
|
||||
"dfg-exception-try-catch-in-constructor-with-inlined-throw.js",
|
||||
"dfg-call-class-constructor.js",
|
||||
"dfg-osr-entry-should-not-use-callframe-argument.js",
|
||||
// Allocation sinking / OSR / LICM
|
||||
"varargs-inlined-simple-exit.js",
|
||||
"loop-unrolling.js",
|
||||
"licm-no-pre-header.js",
|
||||
];
|
||||
|
||||
const wasmFixtures = [
|
||||
// BBQ
|
||||
"bbq-fusedif-register-alloc.js",
|
||||
"bbq-osr-with-exceptions.js",
|
||||
"ipint-bbq-osr-with-try.js",
|
||||
"ipint-bbq-osr-with-try2.js",
|
||||
"ipint-bbq-osr-with-try3.js",
|
||||
"ipint-bbq-osr-with-try4.js",
|
||||
"ipint-bbq-osr-with-try5.js",
|
||||
"ipint-bbq-osr-check-try-implicit-slot-overlap.js",
|
||||
"ipint-bbq-osr-check-try-implicit-slot-overlap2.js",
|
||||
"zero-clear-bbq-address.js",
|
||||
"tail-call-should-consume-stack-in-bbq.js",
|
||||
// OMG
|
||||
"omg-recompile-from-two-bbq.js",
|
||||
"omg-osr-stack-slot-positioning.js",
|
||||
"omg-tail-call-clobber-pinned-registers.js",
|
||||
"omg-tail-call-to-function-with-less-arguments.js",
|
||||
"omg-tail-call-clobber-scratch-register.js",
|
||||
"omg-osr-stack-check-2.js",
|
||||
];
|
||||
|
||||
const preloadPath = path.join(import.meta.dir, "preload.js");
|
||||
|
||||
describe.concurrent("JSC JIT Stress Tests", () => {
|
||||
describe("JS (Baseline/DFG/FTL)", () => {
|
||||
for (const fixture of jsFixtures) {
|
||||
test(fixture, async () => {
|
||||
const fixturePath = path.join(fixturesDir, fixture);
|
||||
const jscEnv = parseJSCFlags(fixturePath);
|
||||
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "--preload", preloadPath, fixturePath],
|
||||
env: { ...bunEnv, ...jscEnv },
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([
|
||||
new Response(proc.stdout).text(),
|
||||
new Response(proc.stderr).text(),
|
||||
proc.exited,
|
||||
]);
|
||||
|
||||
if (exitCode !== 0) {
|
||||
console.log("stdout:", stdout);
|
||||
console.log("stderr:", stderr);
|
||||
}
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe("Wasm (BBQ/OMG)", () => {
|
||||
for (const fixture of wasmFixtures) {
|
||||
test(fixture, async () => {
|
||||
const fixturePath = path.join(wasmFixturesDir, fixture);
|
||||
const jscEnv = parseJSCFlags(fixturePath);
|
||||
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "--preload", preloadPath, fixturePath],
|
||||
env: { ...bunEnv, ...jscEnv },
|
||||
cwd: wasmFixturesDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([
|
||||
new Response(proc.stdout).text(),
|
||||
new Response(proc.stderr).text(),
|
||||
proc.exited,
|
||||
]);
|
||||
|
||||
if (exitCode !== 0) {
|
||||
console.log("stdout:", stdout);
|
||||
console.log("stderr:", stderr);
|
||||
}
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
18
test/js/bun/jsc-stress/preload.js
Normal file
18
test/js/bun/jsc-stress/preload.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// JSC test harness polyfills for Bun
|
||||
// These globals are used by JSC stress tests but are not available in Bun.
|
||||
|
||||
// noInline: hints JSC to not inline the function. No-op in Bun.
|
||||
globalThis.noInline = require("bun:jsc").noInline;
|
||||
|
||||
// testLoopCount: iteration count to trigger JIT tier-up (Baseline -> DFG -> FTL).
|
||||
globalThis.testLoopCount = 10000;
|
||||
|
||||
// print: JSC's output function, mapped to console.log.
|
||||
globalThis.print = console.log;
|
||||
|
||||
// Wasm test polyfills
|
||||
globalThis.callerIsBBQOrOMGCompiled = function () {
|
||||
return 1;
|
||||
};
|
||||
if (!globalThis.$) globalThis.$ = {};
|
||||
if (!$.agent) $.agent = { report: function () {} };
|
||||
Reference in New Issue
Block a user