* Cranelift: Define `heap_load` and `heap_store` instructions
* Cranelift: Implement interpreter support for `heap_load` and `heap_store`
* Cranelift: Add a suite runtests for `heap_{load,store}`
There are so many knobs we can twist for heaps and I wanted to exhaustively test
all of them, so I wrote a script to generate the tests. I've checked in the
script in case we want to make any changes in the future, but I don't think it
is worth adding this to CI to check that scripts are up to date or anything like
that.
* Review feedback
91 lines
2.1 KiB
Bash
Executable File
91 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This script generates the `heap_load_store_*.clif` test files.
|
|
#
|
|
# Usage:
|
|
#
|
|
# $ ./make-heap-load-store-tests.sh
|
|
|
|
set -e
|
|
cd $(dirname "$0")
|
|
|
|
function generate_one_test() {
|
|
local kind=$1
|
|
local index_type=$2
|
|
local guard=$3
|
|
local spectre=$4
|
|
|
|
local enable_spectre=true
|
|
if [[ spectre == "no" ]]; then
|
|
enable_spectre=false
|
|
fi
|
|
|
|
local have_guards=yes
|
|
if [[ guard == "0" ]]; then
|
|
have_guards=no
|
|
fi
|
|
|
|
local gv2=""
|
|
local bound=0x1000
|
|
if [[ $kind == "dynamic" ]]; then
|
|
gv2="gv2 = load.i64 notrap aligned gv0+8"
|
|
bound=gv2
|
|
fi
|
|
|
|
local filename="heap_load_store_${kind}_${index_type}_${have_guards}_guards_${spectre}_spectre.clif"
|
|
echo "Generating $filename"
|
|
|
|
cat <<EOF > "$filename"
|
|
;; !!! GENERATED BY 'make-heap-load-store-tests.sh' DO NOT EDIT !!!
|
|
|
|
test interpret
|
|
;; test run
|
|
;; target x86_64
|
|
;; target s390x
|
|
;; target aarch64
|
|
;; target riscv64
|
|
|
|
set enable_heap_access_spectre_mitigation=${enable_spectre}
|
|
|
|
function %do_store(i64 vmctx, ${index_type}, i32) {
|
|
gv0 = vmctx
|
|
gv1 = load.i64 notrap aligned gv0+0
|
|
$gv2
|
|
heap0 = ${kind} gv1, min 0x1000, bound ${bound}, offset_guard ${guard}, index_type ${index_type}
|
|
|
|
block0(v0: i64, v1: ${index_type}, v2: i32):
|
|
heap_store.i32 heap0 little v1+4, v2
|
|
return
|
|
}
|
|
|
|
function %test(i64 vmctx, ${index_type}, i32) -> i32 {
|
|
gv0 = vmctx
|
|
gv1 = load.i64 notrap aligned gv0+0
|
|
$gv2
|
|
heap0 = ${kind} gv1, min 0x1000, bound ${bound}, offset_guard ${guard}, index_type ${index_type}
|
|
fn0 = %do_store(i64, ${index_type}, i32)
|
|
|
|
block0(v0: i64, v1: ${index_type}, v2: i32):
|
|
call fn0(v0, v1, v2)
|
|
v3 = heap_load.i32 heap0 little v1+4
|
|
return v3
|
|
}
|
|
; heap: ${kind}, size=0x1000, ptr=vmctx+0, bound=vmctx+8
|
|
; run: %test(0, 0) == 0
|
|
; run: %test(0, -1) == -1
|
|
; run: %test(16, 1) == 1
|
|
; run: %test(16, -1) == -1
|
|
; run: %test(2049, 0xaabb_ccdd) == 0xaabb_ccdd
|
|
EOF
|
|
}
|
|
|
|
for spectre in yes no; do
|
|
for guard in 0 0xffff_ffff; do
|
|
for index_type in i32 i64; do
|
|
for kind in static dynamic; do
|
|
generate_one_test $kind $index_type $guard $spectre
|
|
done
|
|
done
|
|
done
|
|
done
|