diff --git a/crates/interpreter/CHANGELOG.md b/crates/interpreter/CHANGELOG.md index 0f2f84b6..d88642a9 100644 --- a/crates/interpreter/CHANGELOG.md +++ b/crates/interpreter/CHANGELOG.md @@ -4,7 +4,7 @@ ### Minor -- Use `atomic-polyfill` to support RV32IMC +- Use `portable-atomic` to support RV32IMC ### Patch diff --git a/crates/interpreter/Cargo.lock b/crates/interpreter/Cargo.lock index 03680c32..8588ceb4 100644 --- a/crates/interpreter/Cargo.lock +++ b/crates/interpreter/Cargo.lock @@ -13,27 +13,12 @@ dependencies = [ "version_check", ] -[[package]] -name = "atomic-polyfill" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" -dependencies = [ - "critical-section", -] - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "critical-section" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" - [[package]] name = "hashbrown" version = "0.13.1" @@ -108,6 +93,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +[[package]] +name = "portable-atomic" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f602a0d1e09a48e4f8e8b4d4042e32807c3676da31f2ecabeac9f96226ec6c45" + [[package]] name = "proc-macro2" version = "1.0.56" @@ -159,12 +150,12 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" name = "wasefire-interpreter" version = "0.1.2-git" dependencies = [ - "atomic-polyfill", "lazy_static", "libm", "lru", "num_enum", "paste", + "portable-atomic", "wast", ] diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index cf1c112e..674dda9e 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -12,11 +12,11 @@ keywords = ["embedded", "framework", "no-std", "wasm"] categories = ["embedded", "no-std", "wasm"] [dependencies] -atomic-polyfill = "1.0.2" libm = { version = "0.2.6", optional = true } lru = { version = "0.10.0", optional = true } num_enum = { version = "0.6.0", default-features = false } paste = "1.0.12" +portable-atomic = { version = "1.2.0", default-features = false } [dev-dependencies] lazy_static = "1.4.0" diff --git a/crates/interpreter/src/id.rs b/crates/interpreter/src/id.rs index 80535d6c..c6d33f8f 100644 --- a/crates/interpreter/src/id.rs +++ b/crates/interpreter/src/id.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use atomic_polyfill::{AtomicUsize, Ordering}; +use portable_atomic::{AtomicUsize, Ordering}; /// Returns numbers from 1 to u32::MAX (inclusive). pub struct UniqueId { diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index ba39f06a..1320dc56 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -89,6 +89,20 @@ //! } //! # } //! ``` +//! +//! # Atomic support +//! +//! This crate uses atomic operations and relies on the `portable-atomic` crate to support +//! architectures without atomic operations. Depending on your architecture, you may need one of the +//! following: +//! +//! - Enable the `portable-atomic/critical-section` feature (possibly adding a direct dependency on +//! `portable-atomic`). +//! +//! - Set the `--cfg=portable_atomic_unsafe_assume_single_core` rustc flag. +//! +//! You can find more information in the `portable-atomic` +//! [documentation](https://docs.rs/portable-atomic/latest/portable_atomic). #![cfg_attr(not(feature = "debug"), no_std)] #![cfg_attr(not(feature = "toctou"), feature(slice_split_at_unchecked))] diff --git a/crates/interpreter/src/runtime.rs b/crates/interpreter/src/runtime.rs deleted file mode 100644 index 19abbda1..00000000 --- a/crates/interpreter/src/runtime.rs +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use alloc::vec::Vec; -use core::marker::PhantomData; -use core::sync::atomic::{AtomicBool, Ordering}; - -use crate::module::*; -use crate::syntax::*; -use crate::*; - -// TODO: Introduce untyped values? (to save the tag) -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Val { - I32(u32), - I64(u64), - F32(u32), - F64(u64), - // TODO: Gate v128 with a feature to save RAM. Or Box it. - V128(u128), - Null(RefType), - Ref(usize), - RefExtern(usize), -} - -#[derive(Debug, Default)] -pub struct Store<'m> { - singleton: StoreSingleton, - funcs: Vec>, - tables: Vec, - mems: Vec>, - globals: Vec, - elems: Vec, - datas: Vec>, - modules: Vec>, -} - -#[derive(Debug)] -pub struct ModuleInst<'m> { - pub module: Module<'m>, - pub funcaddrs: Vec>>, - pub tableaddrs: Vec>, - pub memaddrs: Vec>>, - pub globaladdrs: Vec>, - pub exports: Vec>, - pub elemaddrs: Vec, - pub dataaddrs: Vec, -} - -#[derive(Debug)] -pub enum FuncInst<'m> { - Guest { - type_: FuncType<'m>, - module: Addr>, - code: Parser<'m>, - }, - Host { - type_: FuncType<'m>, - // hostcode: HostCode, - }, -} - -impl<'m> FuncInst<'m> { - pub fn type_(&self) -> FuncType<'m> { - match self { - FuncInst::Guest { type_, .. } | FuncInst::Host { type_ } => *type_, - } - } -} - -#[derive(Debug)] -pub struct TableInst { - type_: TableType, - elem: Vec, -} - -// Invariants: -// - type_.min <= size <= type_.max -// - data.len() <= type_.max * 64K -// Accessing data between data.len() and size * 64K triggers a trap. -#[derive(Debug)] -pub struct MemInst<'m> { - type_: MemType, - data: &'m mut [u8], - size: u32, -} - -#[derive(Debug)] -pub struct GlobalInst { - type_: GlobalType, - value: Val, -} - -#[derive(Debug)] -pub struct ElemInst { - type_: RefType, - elem: Vec, // TODO: Should probably be done lazily. -} - -#[derive(Debug)] -pub struct DataInst<'m> { - data: &'m [u8], -} - -#[derive(Debug)] -pub struct ExportInst<'m> { - name: &'m str, - value: ExternVal<'m>, -} - -#[derive(Debug)] -pub enum ExternVal<'m> { - Func(Addr>), - Table(Addr), - Mem(Addr>), - Global(Addr), -} - -impl<'m> ExternVal<'m> { - // TODO: This should actually return Invalid instead of panic. - pub fn type_(&self, store: &Store) -> ExternType<'m> { - match *self { - ExternVal::Func(a) => ExternType::Func(store.get(a).type_()), - ExternVal::Table(a) => ExternType::Table(store.get(a).type_), - ExternVal::Mem(a) => ExternType::Mem(store.get(a).type_), - ExternVal::Global(a) => ExternType::Global(store.get(a).type_), - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct Addr { - addr: usize, - _type: PhantomData, -} - -trait Data<'m>: Sized { - fn list<'a>(store: &'a Store<'m>) -> &'a [Self]; - fn list_mut<'a>(store: &'a mut Store<'m>) -> &'a mut Vec; -} - -macro_rules! impl_data { - ($n:ident: $t:ty) => { - impl<'m> Data<'m> for $t { - fn list<'a>(store: &'a Store<'m>) -> &'a [Self] { - &store.$n - } - fn list_mut<'a>(store: &'a mut Store<'m>) -> &'a mut Vec { - &mut store.$n - } - } - }; -} -impl_data!(funcs: FuncInst<'m>); -impl_data!(tables: TableInst); -impl_data!(mems: MemInst<'m>); -impl_data!(globals: GlobalInst); -impl_data!(modules: ModuleInst<'m>); - -impl<'m> Store<'m> { - pub fn get>(&self, p: Addr) -> &T { - &::list(self)[p.addr] - } - - pub fn insert>(&mut self, x: T) -> Addr { - let xs = ::list_mut(self); - let addr = Addr { addr: xs.len(), _type: PhantomData }; - xs.push(x); - addr - } -} - -#[derive(Debug)] -pub enum Stack<'m> { - Frames(Vec>), - Result(Vec), - Trap, -} - -#[derive(Debug)] -pub struct Frame<'m> { - arity: usize, - locals: Vec, - module: Addr>, - labels: Vec>, -} - -#[derive(Debug)] -pub struct Label<'m> { - arity: usize, - cont: Option<&'m [u8]>, - values: Vec, -} - -#[derive(Debug)] -struct StoreSingleton; -impl Default for StoreSingleton { - fn default() -> Self { - static EXISTS: AtomicBool = AtomicBool::new(false); - assert!(!EXISTS.swap(true, Ordering::SeqCst)); - Self - } -} diff --git a/crates/interpreter/test.sh b/crates/interpreter/test.sh index 4dbded32..5eeff6c7 100755 --- a/crates/interpreter/test.sh +++ b/crates/interpreter/test.sh @@ -17,7 +17,10 @@ set -ex cargo check cargo check --target=thumbv7em-none-eabi -cargo check --target=riscv32imc-unknown-none-elf +cargo check --target=riscv32imc-unknown-none-elf \ + --features=portable-atomic/critical-section +RUSTFLAGS=--cfg=portable_atomic_unsafe_assume_single_core \ + cargo check --target=riscv32imc-unknown-none-elf cargo fmt -- --check cargo clippy -- --deny=warnings [ -e ../../third_party/WebAssembly/spec/.git ] || git submodule update --init diff --git a/crates/runner-host/Cargo.lock b/crates/runner-host/Cargo.lock index 5c2a164d..d2883116 100644 --- a/crates/runner-host/Cargo.lock +++ b/crates/runner-host/Cargo.lock @@ -78,15 +78,6 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" -[[package]] -name = "atomic-polyfill" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" -dependencies = [ - "critical-section", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -205,12 +196,6 @@ dependencies = [ "libc", ] -[[package]] -name = "critical-section" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" - [[package]] name = "crypto-common" version = "0.1.6" @@ -530,6 +515,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "portable-atomic" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f602a0d1e09a48e4f8e8b4d4042e32807c3676da31f2ecabeac9f96226ec6c45" + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -867,9 +858,9 @@ dependencies = [ name = "wasefire-interpreter" version = "0.1.2-git" dependencies = [ - "atomic-polyfill", "num_enum", "paste", + "portable-atomic", ] [[package]] diff --git a/crates/runner-nordic/Cargo.lock b/crates/runner-nordic/Cargo.lock index bc0d38ba..6f9754f7 100644 --- a/crates/runner-nordic/Cargo.lock +++ b/crates/runner-nordic/Cargo.lock @@ -48,15 +48,6 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" -[[package]] -name = "atomic-polyfill" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" -dependencies = [ - "critical-section", -] - [[package]] name = "az" version = "1.2.1" @@ -533,6 +524,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +[[package]] +name = "portable-atomic" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f602a0d1e09a48e4f8e8b4d4042e32807c3676da31f2ecabeac9f96226ec6c45" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -821,9 +818,9 @@ dependencies = [ name = "wasefire-interpreter" version = "0.1.2-git" dependencies = [ - "atomic-polyfill", "num_enum", "paste", + "portable-atomic", ] [[package]] diff --git a/crates/scheduler/Cargo.lock b/crates/scheduler/Cargo.lock index 43bf21de..3eb581d5 100644 --- a/crates/scheduler/Cargo.lock +++ b/crates/scheduler/Cargo.lock @@ -48,15 +48,6 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" -[[package]] -name = "atomic-polyfill" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" -dependencies = [ - "critical-section", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -132,12 +123,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "critical-section" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" - [[package]] name = "data-encoding" version = "2.3.3" @@ -344,6 +329,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +[[package]] +name = "portable-atomic" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f602a0d1e09a48e4f8e8b4d4042e32807c3676da31f2ecabeac9f96226ec6c45" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -550,9 +541,9 @@ dependencies = [ name = "wasefire-interpreter" version = "0.1.2-git" dependencies = [ - "atomic-polyfill", "num_enum", "paste", + "portable-atomic", ] [[package]]