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:
SUZUKI Sosuke
2026-01-26 17:21:34 +09:00
committed by GitHub
parent 799907362f
commit a595fe1cca
83 changed files with 8029 additions and 0 deletions

View 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.

View File

@@ -0,0 +1,5 @@
[run]
preload = "./preload.js"
[test]
preload = "./preload.js"

View 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());
}

View File

@@ -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";
}

View File

@@ -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!");

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());
});
}

View File

@@ -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();

View File

@@ -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));
}

View 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;
}

View 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()

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View 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"
}

View 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"
}

View 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"
}

View 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}`;
}

View File

@@ -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;

View 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];

View File

@@ -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];

View 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);
}

View 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);
}

View 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;

View File

@@ -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];

View File

@@ -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];

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View 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;
}

View 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);

View 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);
}

View File

@@ -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;

View File

@@ -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);
}

View 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;

View File

@@ -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();

View 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;
}

View File

@@ -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;

View 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];

View File

@@ -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.";

View File

@@ -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];

View File

@@ -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];

View 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";
}

View 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";
}

View 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;

View 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;
}

View 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;

View 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 + " but expected " + expected;
}

View 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;

View 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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);

View File

@@ -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");

View File

@@ -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]);

View 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;

View 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]);

View 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);

View File

@@ -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

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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('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', 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');
})

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

View 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");
});

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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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()

View File

@@ -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();

View 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);
});
}
});
});

View 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 () {} };