Skip to content

Commit 20154c5

Browse files
Julius Rakowpepyakin
authored andcommitted
Add no_std support (#122)
* add default-enabled std feature * use parity-wasm/std feature only if std is enabled * drop dependency on std::io * use hashmap_core instead of std::collections::HashMap * disable std::error in no_std * core and alloc all the things * mention no_std in readme * add no_std feature and use hashmap_core only on no_std * rename the no_std feature to core * drop dependency on byteorder/std * simplify float impl macro * remove some trailing whitespace * use libm for float math in no_std * add note about no_std panics of libm to readme * Embed nan-preserving-float crate. * Add no_std check to the Travis CI config * add missing dev-dependency
1 parent 2f7505d commit 20154c5

23 files changed

+452
-121
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ script:
2323
# Make sure nightly targets are not broken.
2424
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo check --tests --manifest-path=fuzz/Cargo.toml; fi
2525
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo check --benches --manifest-path=benches/Cargo.toml; fi
26+
# Make sure `no_std` version checks.
27+
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo +nightly check --no-default-features --features core; fi
2628
- ./test.sh
2729
- ./doc.sh
2830
after_success: |

Cargo.toml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,22 @@ description = "WebAssembly interpreter"
1010
keywords = ["wasm", "webassembly", "bytecode", "interpreter"]
1111
exclude = [ "/res/*", "/tests/*", "/fuzz/*", "/benches/*" ]
1212

13+
[features]
14+
default = ["std"]
15+
# Disable for no_std support
16+
std = ["parity-wasm/std", "byteorder/std"]
17+
# Enable for no_std support
18+
# hashmap_core only works on no_std
19+
core = ["hashmap_core", "libm"]
20+
1321
[dependencies]
14-
parity-wasm = "0.31"
15-
byteorder = "1.0"
22+
parity-wasm = { version = "0.31", default-features = false }
23+
byteorder = { version = "1.0", default-features = false }
24+
hashmap_core = { version = "0.1.9", optional = true }
1625
memory_units = "0.3.0"
17-
nan-preserving-float = "0.1.0"
26+
libm = { version = "0.1.2", optional = true }
1827

1928
[dev-dependencies]
2029
assert_matches = "1.1"
30+
rand = "0.4.2"
2131
wabt = "0.6"

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ cargo build
2727
cargo test
2828
```
2929

30+
# `no_std` support
31+
This crate supports `no_std` environments.
32+
Enable the `core` feature and disable default features:
33+
```toml
34+
[dependencies]
35+
parity-wasm = {
36+
version = "0.31",
37+
default-features = false,
38+
features = "core"
39+
}
40+
```
41+
42+
The `core` feature requires the `core` and `alloc` libraries and a nightly compiler.
43+
Also, code related to `std::error` is disabled.
44+
45+
Floating point operations in `no_std` use [`libm`](https://crates.io/crates/libm), which sometimes panics in debug mode (https://github.com/japaric/libm/issues/4).
46+
So make sure to either use release builds or avoid WASM with floating point operations, for example by using [`deny_floating_point`](https://docs.rs/wasmi/0.4.0/wasmi/struct.Module.html#method.deny_floating_point).
47+
3048
## Contribution
3149

3250
Unless you explicitly state otherwise, any contribution intentionally submitted

src/common/stack.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
#[allow(unused_imports)]
2+
use alloc::prelude::*;
13

4+
#[cfg(feature = "std")]
25
use std::error;
3-
use std::fmt;
6+
use core::fmt;
47

58
#[derive(Debug)]
69
pub struct Error(String);
@@ -11,6 +14,7 @@ impl fmt::Display for Error {
1114
}
1215
}
1316

17+
#[cfg(feature = "std")]
1418
impl error::Error for Error {
1519
fn description(&self) -> &str {
1620
&self.0

src/func.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use std::rc::{Rc, Weak};
2-
use std::fmt;
1+
#[allow(unused_imports)]
2+
use alloc::prelude::*;
3+
use alloc::rc::{Rc, Weak};
4+
use core::fmt;
35
use parity_wasm::elements::Local;
46
use {Trap, TrapKind, Signature};
57
use host::Externals;
@@ -17,7 +19,7 @@ use isa;
1719
#[derive(Clone, Debug)]
1820
pub struct FuncRef(Rc<FuncInstance>);
1921

20-
impl ::std::ops::Deref for FuncRef {
22+
impl ::core::ops::Deref for FuncRef {
2123
type Target = FuncInstance;
2224
fn deref(&self) -> &FuncInstance {
2325
&self.0

src/global.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::rc::Rc;
2-
use std::cell::Cell;
1+
use alloc::rc::Rc;
2+
use core::cell::Cell;
33
use value::RuntimeValue;
44
use Error;
55
use types::ValueType;
@@ -13,7 +13,7 @@ use parity_wasm::elements::{ValueType as EValueType};
1313
#[derive(Clone, Debug)]
1414
pub struct GlobalRef(Rc<GlobalInstance>);
1515

16-
impl ::std::ops::Deref for GlobalRef {
16+
impl ::core::ops::Deref for GlobalRef {
1717
type Target = GlobalInstance;
1818
fn deref(&self) -> &GlobalInstance {
1919
&self.0

src/host.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::any::TypeId;
1+
use core::any::TypeId;
22
use value::{RuntimeValue, FromRuntimeValue};
33
use {TrapKind, Trap};
44

@@ -98,7 +98,7 @@ impl<'a> RuntimeArgs<'a> {
9898
/// _ => panic!(),
9999
/// }
100100
/// ```
101-
pub trait HostError: 'static + ::std::fmt::Display + ::std::fmt::Debug + Send + Sync {
101+
pub trait HostError: 'static + ::core::fmt::Display + ::core::fmt::Debug + Send + Sync {
102102
#[doc(hidden)]
103103
fn __private_get_type_id__(&self) -> TypeId {
104104
TypeId::of::<Self>()

src/imports.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
#[allow(unused_imports)]
2+
use alloc::prelude::*;
3+
4+
#[cfg(feature = "std")]
15
use std::collections::HashMap;
6+
#[cfg(not(feature = "std"))]
7+
use hashmap_core::HashMap;
8+
29
use global::GlobalRef;
310
use memory::MemoryRef;
411
use func::FuncRef;

src/isa.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
//! - Reserved immediates are ignored for `call_indirect`, `current_memory`, `grow_memory`.
6868
//!
6969
70+
#[allow(unused_imports)]
71+
use alloc::prelude::*;
72+
7073
/// Should we keep a value before "discarding" a stack frame?
7174
///
7275
/// Note that this is a `enum` since Wasm doesn't support multiple return

src/lib.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@
9696
9797
#![warn(missing_docs)]
9898

99+
#![cfg_attr(not(feature = "std"), no_std)]
100+
101+
//// alloc is required in no_std
102+
#![cfg_attr(not(feature = "std"), feature(alloc))]
103+
104+
#[cfg(not(feature = "std"))]
105+
#[macro_use]
106+
extern crate alloc;
107+
#[cfg(feature = "std")]
108+
extern crate std as alloc;
109+
110+
#[cfg(feature = "std")]
111+
#[macro_use]
112+
extern crate core;
113+
99114
#[cfg(test)]
100115
extern crate wabt;
101116
#[cfg(test)]
@@ -104,13 +119,19 @@ extern crate assert_matches;
104119

105120
extern crate parity_wasm;
106121
extern crate byteorder;
122+
#[cfg(not(feature = "std"))]
123+
extern crate hashmap_core;
107124
extern crate memory_units as memory_units_crate;
108125

109-
pub extern crate nan_preserving_float;
110-
111-
use std::fmt;
126+
#[allow(unused_imports)]
127+
use alloc::prelude::*;
128+
use core::fmt;
129+
#[cfg(feature = "std")]
112130
use std::error;
113131

132+
#[cfg(not(feature = "std"))]
133+
extern crate libm;
134+
114135
/// Error type which can be thrown by wasm code or by host environment.
115136
///
116137
/// Under some conditions, wasm execution may produce a `Trap`, which immediately aborts execution.
@@ -138,6 +159,7 @@ impl fmt::Display for Trap {
138159
}
139160
}
140161

162+
#[cfg(feature = "std")]
141163
impl error::Error for Trap {
142164
fn description(&self) -> &str {
143165
"runtime trap"
@@ -308,6 +330,7 @@ impl fmt::Display for Error {
308330
}
309331
}
310332

333+
#[cfg(feature = "std")]
311334
impl error::Error for Error {
312335
fn description(&self) -> &str {
313336
match *self {
@@ -367,6 +390,7 @@ mod global;
367390
mod func;
368391
mod types;
369392
mod isa;
393+
pub mod nan_preserving_float;
370394

371395
#[cfg(test)]
372396
mod tests;

0 commit comments

Comments
 (0)