Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions ci/build-test-matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function supports32Bit(pkg) {
if (pkg.indexOf("pulley") !== -1)
return true;

return pkg == 'wasmtime-fiber';
return pkg == 'wasmtime-fiber' || pkg == 'wasmtime';
}

// This is the full, unsharded, and unfiltered matrix of what we test on
Expand Down Expand Up @@ -231,7 +231,9 @@ async function shard(configs) {
for (const config of configs) {
// Special case 32-bit configs. Only some crates, according to
// `supports32Bit`, run on this target. At this time the set of supported
// crates is small enough that they're not sharded.
// crates is small enough that they're not sharded. A second shard, however,
// is included which runs `--test wast` to run the full `*.wast` test suite
// in CI on 32-bit platforms, at this time effectively testing Pulley.
if (config["32-bit"] === true) {
sharded.push(Object.assign(
{},
Expand All @@ -242,6 +244,11 @@ async function shard(configs) {
.join(" "),
}
));
sharded.push(Object.assign(
{},
config,
{ bucket: '--test wast' },
));
Comment on lines +247 to +251
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not going to break for the crates which support 32-bit but don't have a tests/wast.rs? I.e. all of them other than wasmtime? But even the wasmtime crate doesn't have that test, only wasmtime-cli does... I guess I am pretty confused around the logic here...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is abusing the fact that cargo test --workspace --test wast only actually executes tests named wast and everything else is ignored. So this effectively runs cargo test --test wast and nothing else is named wast.

In the long-run I want to get more 32-bit tests running, just needs more support in Pulley for that.

continue;
}

Expand Down
12 changes: 10 additions & 2 deletions cranelift/codegen/src/isa/pulley_shared/abi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Implementation of a standard Pulley ABI.

use super::{inst::*, PulleyFlags, PulleyTargetKind};
use crate::isa::pulley_shared::PulleyBackend;
use crate::isa::pulley_shared::{PointerWidth, PulleyBackend};
use crate::{
ir::{self, types::*, MemFlags, Signature},
isa::{self, unwind::UnwindInst},
Expand Down Expand Up @@ -533,7 +533,15 @@ where
_isa_flags: &PulleyFlags,
) -> u32 {
match rc {
RegClass::Int => 1,
// Spilling an integer register requires spilling 8 bytes, and spill
// slots are defined in terms of "word bytes" or the size of a
// pointer. That means on 32-bit pulley we need to take up two spill
// slots for integers where on 64-bit pulley we need to only take up
// one spill slot for integers.
RegClass::Int => match P::pointer_width() {
PointerWidth::PointerWidth32 => 2,
PointerWidth::PointerWidth64 => 1,
},
RegClass::Float => todo!(),
RegClass::Vector => unreachable!(),
}
Expand Down
2 changes: 1 addition & 1 deletion cranelift/jit/src/compiled_blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl CompiledBlob {
let at_page = (at as usize) & !0xfff;
let pcrel = (what_page as isize).checked_sub(at_page as isize).unwrap();
assert!(
(-1 << 32) <= pcrel && pcrel < (1 << 32),
(-1 << 32) <= (pcrel as i64) && (pcrel as i64) < (1 << 32),
"can't reach GOT page with ±4GB `adrp` instruction"
);
let val = pcrel >> 12;
Expand Down
8 changes: 5 additions & 3 deletions crates/wasi-nn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@ wasmtime = { workspace = true, features = [
# These dependencies are necessary for the wasi-nn implementation:
tracing = { workspace = true }
thiserror = { workspace = true }
openvino = { version = "0.8.0", features = [
"runtime-linking",
], optional = true }

ort = { version = "2.0.0-rc.2", default-features = false, features = [
"copy-dylibs",
"download-binaries",
], optional = true }
tch = { version = "0.17.0", default-features = false, optional = true}

[target.'cfg(target_pointer_width = "64")'.dependencies]
openvino = { version = "0.8.0", features = [
"runtime-linking",
], optional = true }

[target.'cfg(windows)'.dependencies.windows]
version = "0.52"
features = [
Expand Down
8 changes: 5 additions & 3 deletions crates/wasi-nn/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#[cfg(feature = "onnx")]
pub mod onnx;
#[cfg(feature = "openvino")]
#[cfg(all(feature = "openvino", target_pointer_width = "64"))]
pub mod openvino;
#[cfg(feature = "pytorch")]
pub mod pytorch;
Expand All @@ -13,7 +13,7 @@ pub mod winml;

#[cfg(feature = "onnx")]
use self::onnx::OnnxBackend;
#[cfg(feature = "openvino")]
#[cfg(all(feature = "openvino", target_pointer_width = "64"))]
use self::openvino::OpenvinoBackend;
#[cfg(feature = "pytorch")]
use self::pytorch::PytorchBackend;
Expand All @@ -31,7 +31,8 @@ use wiggle::GuestError;
/// Return a list of all available backend frameworks.
pub fn list() -> Vec<Backend> {
let mut backends = vec![];
#[cfg(feature = "openvino")]
let _ = &mut backends; // silence warnings if none are enabled
#[cfg(all(feature = "openvino", target_pointer_width = "64"))]
{
backends.push(Backend::from(OpenvinoBackend::default()));
}
Expand Down Expand Up @@ -120,6 +121,7 @@ pub enum BackendError {
}

/// Read a file into a byte vector.
#[allow(dead_code, reason = "not used on all platforms")]
fn read(path: &Path) -> anyhow::Result<Vec<u8>> {
let mut file = File::open(path)?;
let mut buffer = vec![];
Expand Down
5 changes: 5 additions & 0 deletions crates/wasmtime/src/engine/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,8 @@ mod test {
}

#[test]
#[cfg(target_arch = "x86_64")] // test on a platform that is known to use
// Cranelift
fn test_os_mismatch() -> Result<()> {
let engine = Engine::default();
let mut metadata = Metadata::new(&engine);
Expand Down Expand Up @@ -712,6 +714,7 @@ Caused by:

#[test]
#[cfg_attr(miri, ignore)]
#[cfg(target_pointer_width = "64")] // different defaults on 32-bit platforms
fn test_tunables_int_mismatch() -> Result<()> {
let engine = Engine::default();
let mut metadata = Metadata::new(&engine);
Expand Down Expand Up @@ -762,6 +765,8 @@ Caused by:
}

#[test]
#[cfg(target_arch = "x86_64")] // test on a platform that is known to
// implement threads
fn test_feature_mismatch() -> Result<()> {
let mut config = Config::new();
config.wasm_threads(true);
Expand Down
16 changes: 15 additions & 1 deletion crates/wasmtime/src/runtime/externals/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ impl Table {
mod tests {
use super::*;
use crate::{Instance, Module, Store};
use wasmtime_environ::TripleExt;

#[test]
fn hash_key_is_stable_across_duplicate_store_data_entries() -> Result<()> {
Expand All @@ -452,7 +453,20 @@ mod tests {
(table (export "t") 1 1 externref)
)
"#,
)?;
);
// Expect this test to fail on pulley at this time. When pulley supports
// externref this should switch back to using `?` on the constructor
// above for all platforms.
let module = match module {
Ok(module) => {
assert!(!store.engine().target().is_pulley());
module
}
Err(e) => {
assert!(store.engine().target().is_pulley(), "bad error {e:?}");
return Ok(());
}
};
let instance = Instance::new(&mut store, &module, &[])?;

// Each time we `get_table`, we call `Table::from_wasmtime` which adds
Expand Down
17 changes: 16 additions & 1 deletion crates/wasmtime/src/runtime/module/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ pub fn unregister_code(code: &Arc<CodeMemory>) {
#[cfg_attr(miri, ignore)]
fn test_frame_info() -> Result<(), anyhow::Error> {
use crate::*;
use wasmtime_environ::TripleExt;

let mut store = Store::<()>::default();
let module = Module::new(
store.engine(),
Expand All @@ -313,7 +315,20 @@ fn test_frame_info() -> Result<(), anyhow::Error> {
(func (export "rem_u") (param $x i32) (param $y i32) (result i32) (i32.rem_u (local.get $x) (local.get $y)))
)
"#,
)?;
);
// Expect this test to fail on pulley at this time. When pulley supports
// the instructions above this should switch back to using `?` on the
// constructor above for all platforms.
let module = match module {
Ok(module) => {
assert!(!store.engine().target().is_pulley());
module
}
Err(e) => {
assert!(store.engine().target().is_pulley(), "bad error {e:?}");
return Ok(());
}
};
// Create an instance to ensure the frame information is registered.
Instance::new(&mut store, &module, &[])?;

Expand Down
40 changes: 26 additions & 14 deletions crates/wasmtime/src/runtime/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,26 +1021,38 @@ mod tests {
fn size_of_val() {
// Try to keep tabs on the size of `Val` and make sure we don't grow its
// size.
assert_eq!(
std::mem::size_of::<Val>(),
if cfg!(any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "riscv64",
target_arch = "s390x"
)) {
24
} else {
panic!("unsupported architecture")
}
);
let expected = if cfg!(target_arch = "x86_64")
|| cfg!(target_arch = "aarch64")
|| cfg!(target_arch = "s390x")
|| cfg!(target_arch = "riscv64")
|| cfg!(target_arch = "arm")
{
24
} else if cfg!(target_arch = "x86") {
20
} else {
panic!("unsupported architecture")
};
assert_eq!(std::mem::size_of::<Val>(), expected);
}

#[test]
fn size_of_ref() {
// Try to keep tabs on the size of `Ref` and make sure we don't grow its
// size.
assert_eq!(std::mem::size_of::<Ref>(), 24);
let expected = if cfg!(target_arch = "x86_64")
|| cfg!(target_arch = "aarch64")
|| cfg!(target_arch = "s390x")
|| cfg!(target_arch = "riscv64")
|| cfg!(target_arch = "arm")
{
24
} else if cfg!(target_arch = "x86") {
20
} else {
panic!("unsupported architecture")
};
assert_eq!(std::mem::size_of::<Ref>(), expected);
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! x86_64-specific definitions of architecture-specific functions in Wasmtime.
//! arm-specific definitions of architecture-specific functions in Wasmtime.

#[inline]
#[allow(missing_docs)]
pub fn get_stack_pointer() -> usize {
let stack_pointer: usize;
unsafe {
core::arch::asm!(
"mov {}, rsp",
"mov {}, sp",
out(reg) stack_pointer,
options(nostack,nomem),
);
Expand All @@ -24,5 +24,5 @@ pub unsafe fn get_next_older_pc_from_fp(fp: usize) -> usize {
pub const NEXT_OLDER_FP_FROM_FP_OFFSET: usize = 0;

pub fn assert_fp_is_aligned(fp: usize) {
assert_eq!(fp % 16, 0, "stack should always be aligned to 16");
assert_eq!(fp % 8, 0, "stack should always be aligned to 8");
}
9 changes: 6 additions & 3 deletions crates/wasmtime/src/runtime/vm/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
//! crate.

cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")] {
mod x86_64;
use x86_64 as imp;
if #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] {
mod x86;
use x86 as imp;
} else if #[cfg(target_arch = "aarch64")] {
mod aarch64;
use aarch64 as imp;
Expand All @@ -20,6 +20,9 @@ cfg_if::cfg_if! {
} else if #[cfg(target_arch = "riscv64")] {
mod riscv64;
use riscv64 as imp;
} else if #[cfg(target_arch = "arm")] {
mod arm;
use arm as imp;
} else {
mod unsupported;
use unsupported as imp;
Expand Down
10 changes: 1 addition & 9 deletions crates/wasmtime/src/runtime/vm/arch/unsupported.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
compile_error!("Wasmtime's runtime is being compiled for an architecture that it does not support");

cfg_if::cfg_if! {
if #[cfg(target_arch = "x86")] {
compile_error!("\
the tracking issue for i686 support is https://github.com/bytecodealliance/wasmtime/issues/1980 \
");
} else if #[cfg(target_arch = "arm")] {
compile_error!("\
the tracking issue for arm support is https://github.com/bytecodealliance/wasmtime/issues/1173 \
");
} else if #[cfg(target_arch = "riscv32")] {
if #[cfg(target_arch = "riscv32")] {
compile_error!("\
the tracking issue for riscv32 support is https://github.com/bytecodealliance/wasmtime/issues/8768 \
");
Expand Down
39 changes: 39 additions & 0 deletions crates/wasmtime/src/runtime/vm/arch/x86.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! x86-specific (also x86-64) definitions of architecture-specific functions in
//! Wasmtime.

#[inline]
#[allow(missing_docs)]
pub fn get_stack_pointer() -> usize {
let stack_pointer: usize;
unsafe {
#[cfg(target_pointer_width = "64")]
core::arch::asm!(
"mov {}, rsp",
out(reg) stack_pointer,
options(nostack,nomem),
);
#[cfg(target_pointer_width = "32")]
core::arch::asm!(
"mov {}, esp",
out(reg) stack_pointer,
options(nostack,nomem),
);
}
stack_pointer
}

pub unsafe fn get_next_older_pc_from_fp(fp: usize) -> usize {
// The calling convention always pushes the return pointer (aka the PC of
// the next older frame) just before this frame.
*(fp as *mut usize).offset(1)
}

// And the current frame pointer points to the next older frame pointer.
pub const NEXT_OLDER_FP_FROM_FP_OFFSET: usize = 0;

/// Frame pointers are aligned if they're aligned to twice the size of a
/// pointer.
pub fn assert_fp_is_aligned(fp: usize) {
let align = 2 * size_of::<usize>();
assert_eq!(fp % align, 0, "stack should always be aligned to {align}");
}
Loading