diff --git a/README.rst b/README.rst index 5d7ae4fde1..59316dff13 100644 --- a/README.rst +++ b/README.rst @@ -35,9 +35,9 @@ the System V AMD64 ABI calling convention used on many platforms, but does not yet support the Windows x64 calling convention. The performance of code produced by Cretonne is not yet impressive, though we have plans to fix that. -The core codegen crates have minimal dependencies, and do not require any host -floating-point support. Support for `no_std` mode in the core codegen crates is -`in development `_. +The core codegen crates have minimal dependencies, support +`no_std <#building-with-no-std>`_ mode, and do not require any host +floating-point support. Cretonne does not yet perform mitigations for Spectre or related security issues, though it may do so in the future. It does not currently make any @@ -90,6 +90,54 @@ You may need to install the *wat2wasm* tool from the `wabt WebAssembly tests. Tests requiring wat2wasm are ignored if the tool is not installed. +Building with `no_std` +---------------------- + +The following crates support `no_std`: + - `cretonne-entity` + - `cretonne-codegen` + - `cretonne-frontend` + - `cretonne-native` + - `cretonne-wasm` + - `cretonne-module` + - `cretonne-simplejit` + - `cretonne` + +To use `no_std` mode, disable the `std` feature and enable the `core` feature. +This currently requires nightly rust. + +For example, to build `cretonne-codegen`: + +.. code-block:: sh + + cd lib/codegen + cargo build --no-default-features --features core + +Or, when using `cretonne-codegen` as a dependency (in Cargo.toml): + +.. code-block:: + + [dependency.cretonne-codegen] + ... + default-features = false + features = ["core"] + +`no_std` support is currently "best effort". We won't try to break it, and +we'll accept patches fixing problems, however we don't expect all developers to +build and test `no_std` when submitting patches. Accordingly, the +`./test-all.sh` script does not test `no_std`. + +There is a separate `./test-no_std.sh` script that tests the `no_std` +support in packages which support it. + +It's important to note that cretonne still needs liballoc to compile. +Thus, whatever environment is used must implement an allocator. + +Also, to allow the use of HashMaps with `no_std`, an external crate called +`hashmap_core` is pulled in (via the `core` feature). This is mostly the same +as `std::collections::HashMap`, except that it doesn't have DOS protection. +Just something to think about. + Building the documentation -------------------------- diff --git a/cranelift/test-no_std.sh b/cranelift/test-no_std.sh new file mode 100755 index 0000000000..7d372f3558 --- /dev/null +++ b/cranelift/test-no_std.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -euo pipefail + +# This is the test script for testing the no_std configuration of +# packages which support it. + +# Repository top-level directory. +cd $(dirname "$0") +topdir=$(pwd) + +function banner() { + echo "====== $@ ======" +} + +# Test those packages which have no_std support. +LIBS="codegen frontend wasm native module simplejit umbrella" +cd "$topdir" +for LIB in $LIBS +do + banner "Rust unit tests in $LIB" + cd "lib/$LIB" + + # Test with just "core" enabled. + cargo test --no-default-features --features core + + # Test with "core" and "std" enabled at the same time. + cargo test --features core + + cd "$topdir" +done + +banner "OK" diff --git a/lib/codegen/Cargo.toml b/lib/codegen/Cargo.toml index 18d0b2aedc..8304c50ca4 100644 --- a/lib/codegen/Cargo.toml +++ b/lib/codegen/Cargo.toml @@ -11,12 +11,26 @@ keywords = ["compile", "compiler", "jit"] build = "build.rs" [dependencies] -cretonne-entity = { path = "../entity", version = "0.5.1" } +cretonne-entity = { path = "../entity", version = "0.5.1", default-features = false } +failure = { version = "0.1.1", default-features = false, features = ["derive"] } +failure_derive = { version = "0.1.1", default-features = false } # It is a goal of the cretonne-codegen crate to have minimal external dependencies. # Please don't add any unless they are essential to the task of creating binary # machine code. Integration tests that need external dependencies can be # accomodated in `tests`. +[dependencies.hashmap_core] +version = "0.1.1" +optional = true + +[features] +# The "std" feature enables use of libstd. The "core" feature enables use +# of some minimal std-like replacement libraries. At least one of these two +# features need to be enabled. +default = ["std"] +std = ["cretonne-entity/std"] +core = ["hashmap_core"] + [badges] maintenance = { status = "experimental" } travis-ci = { repository = "cretonne/cretonne" } diff --git a/lib/codegen/src/bforest/map.rs b/lib/codegen/src/bforest/map.rs index 56e4870679..7cfa824a43 100644 --- a/lib/codegen/src/bforest/map.rs +++ b/lib/codegen/src/bforest/map.rs @@ -3,6 +3,10 @@ use super::{Comparator, Forest, Node, NodeData, NodePool, Path, INNER_SIZE}; use packed_option::PackedOption; use std::marker::PhantomData; +#[cfg(test)] +use std::fmt; +#[cfg(test)] +use std::string::String; /// Tag type defining forest types for a map. struct MapTypes(PhantomData<(K, V, C)>); @@ -207,14 +211,14 @@ where #[cfg(test)] impl Map where - K: Copy + ::std::fmt::Display, + K: Copy + fmt::Display, V: Copy, C: Comparator, { /// Verify consistency. fn verify(&self, forest: &MapForest, comp: &C) where - NodeData>: ::std::fmt::Display, + NodeData>: fmt::Display, { if let Some(root) = self.root.expand() { forest.nodes.verify_tree(root, comp); @@ -223,6 +227,7 @@ where /// Get a text version of the path to `key`. fn tpath(&self, key: K, forest: &MapForest, comp: &C) -> String { + use std::string::ToString; match self.root.expand() { None => "map(empty)".to_string(), Some(root) => { @@ -405,8 +410,8 @@ where #[cfg(test)] impl<'a, K, V, C> MapCursor<'a, K, V, C> where - K: Copy + ::std::fmt::Display, - V: Copy + ::std::fmt::Display, + K: Copy + fmt::Display, + V: Copy + fmt::Display, C: Comparator, { fn verify(&self) { @@ -416,6 +421,7 @@ where /// Get a text version of the path to the current position. fn tpath(&self) -> String { + use std::string::ToString; self.path.to_string() } } diff --git a/lib/codegen/src/bforest/pool.rs b/lib/codegen/src/bforest/pool.rs index eed9402c84..d543991312 100644 --- a/lib/codegen/src/bforest/pool.rs +++ b/lib/codegen/src/bforest/pool.rs @@ -3,6 +3,8 @@ use super::{Forest, Node, NodeData}; use entity::PrimaryMap; use std::ops::{Index, IndexMut}; +#[cfg(test)] +use std::fmt; /// A pool of nodes, including a free list. pub(super) struct NodePool { @@ -74,8 +76,8 @@ impl NodePool { /// Verify the consistency of the tree rooted at `node`. pub fn verify_tree(&self, node: Node, comp: &F::Comparator) where - NodeData: ::std::fmt::Display, - F::Key: ::std::fmt::Display, + NodeData: fmt::Display, + F::Key: fmt::Display, { use super::Comparator; use entity::SparseSet; diff --git a/lib/codegen/src/bforest/set.rs b/lib/codegen/src/bforest/set.rs index d175b1a752..667cd133e2 100644 --- a/lib/codegen/src/bforest/set.rs +++ b/lib/codegen/src/bforest/set.rs @@ -3,6 +3,10 @@ use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE}; use packed_option::PackedOption; use std::marker::PhantomData; +#[cfg(test)] +use std::fmt; +#[cfg(test)] +use std::string::String; /// Tag type defining forest types for a set. struct SetTypes(PhantomData<(K, C)>); @@ -305,7 +309,7 @@ where #[cfg(test)] impl<'a, K, C> SetCursor<'a, K, C> where - K: Copy + ::std::fmt::Display, + K: Copy + fmt::Display, C: Comparator, { fn verify(&self) { @@ -315,6 +319,7 @@ where /// Get a text version of the path to the current position. fn tpath(&self) -> String { + use std::string::ToString; self.path.to_string() } } diff --git a/lib/codegen/src/context.rs b/lib/codegen/src/context.rs index d9dcf7ba87..986ae74d85 100644 --- a/lib/codegen/src/context.rs +++ b/lib/codegen/src/context.rs @@ -23,6 +23,7 @@ use preopt::do_preopt; use regalloc; use result::{CtonError, CtonResult}; use settings::{FlagsOrIsa, OptLevel}; +use std::vec::Vec; use simple_gvn::do_simple_gvn; use timing; use unreachable_code::eliminate_unreachable_code; diff --git a/lib/codegen/src/dbg.rs b/lib/codegen/src/dbg.rs index 0d9f77b76d..8dd47f625d 100644 --- a/lib/codegen/src/dbg.rs +++ b/lib/codegen/src/dbg.rs @@ -8,15 +8,23 @@ /// /// The output will appear in files named `cretonne.dbg.*`, where the suffix is named after the /// thread doing the logging. +#[cfg(feature = "std")] use std::cell::RefCell; +#[cfg(feature = "std")] use std::env; +#[cfg(feature = "std")] use std::ffi::OsStr; use std::fmt; +#[cfg(feature = "std")] use std::fs::File; +#[cfg(feature = "std")] use std::io::{self, Write}; +#[cfg(feature = "std")] use std::sync::atomic; +#[cfg(feature = "std")] use std::thread; +#[cfg(feature = "std")] static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT; /// Is debug tracing enabled? @@ -25,6 +33,7 @@ static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT; /// other than `0`. /// /// This inline function turns into a constant `false` when debug assertions are disabled. +#[cfg(feature = "std")] #[inline] pub fn enabled() -> bool { if cfg!(debug_assertions) { @@ -37,7 +46,15 @@ pub fn enabled() -> bool { } } +/// Does nothing +#[cfg(not(feature = "std"))] +#[inline] +pub fn enabled() -> bool { + false +} + /// Initialize `STATE` from the environment variable. +#[cfg(feature = "std")] fn initialize() -> bool { let enable = match env::var_os("CRETONNE_DBG") { Some(s) => s != OsStr::new("0"), @@ -53,6 +70,7 @@ fn initialize() -> bool { enable } +#[cfg(feature = "std")] thread_local! { static WRITER : RefCell> = RefCell::new(open_file()); } @@ -60,6 +78,7 @@ thread_local! { /// Write a line with the given format arguments. /// /// This is for use by the `dbg!` macro. +#[cfg(feature = "std")] pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> { WRITER.with(|rc| { let mut w = rc.borrow_mut(); @@ -69,6 +88,7 @@ pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> { } /// Open the tracing file for the current thread. +#[cfg(feature = "std")] fn open_file() -> io::BufWriter { let curthread = thread::current(); let tmpstr; @@ -90,6 +110,7 @@ fn open_file() -> io::BufWriter { /// Write a line to the debug trace file if tracing is enabled. /// /// Arguments are the same as for `printf!`. +#[cfg(feature = "std")] #[macro_export] macro_rules! dbg { ($($arg:tt)+) => { @@ -101,6 +122,13 @@ macro_rules! dbg { } } +/// `dbg!` isn't supported in `no_std` mode, so expand it into nothing. +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! dbg { + ($($arg:tt)+) => {} +} + /// Helper for printing lists. pub struct DisplayList<'a, T>(pub &'a [T]) where diff --git a/lib/codegen/src/ir/extname.rs b/lib/codegen/src/ir/extname.rs index dcb3666703..ed723be6fe 100644 --- a/lib/codegen/src/ir/extname.rs +++ b/lib/codegen/src/ir/extname.rs @@ -121,6 +121,7 @@ mod tests { use super::ExternalName; use ir::LibCall; use std::string::ToString; + use std::u32; #[test] fn display_testcase() { @@ -143,7 +144,7 @@ mod tests { assert_eq!(ExternalName::user(0, 0).to_string(), "u0:0"); assert_eq!(ExternalName::user(1, 1).to_string(), "u1:1"); assert_eq!( - ExternalName::user(::std::u32::MAX, ::std::u32::MAX).to_string(), + ExternalName::user(u32::MAX, u32::MAX).to_string(), "u4294967295:4294967295" ); } diff --git a/lib/codegen/src/legalizer/libcall.rs b/lib/codegen/src/legalizer/libcall.rs index dafc353903..17f9174706 100644 --- a/lib/codegen/src/legalizer/libcall.rs +++ b/lib/codegen/src/legalizer/libcall.rs @@ -2,6 +2,7 @@ use ir; use ir::InstBuilder; +use std::vec::Vec; /// Try to expand `inst` as a library call, returning true is successful. pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function) -> bool { diff --git a/lib/codegen/src/lib.rs b/lib/codegen/src/lib.rs index bdb11f5c30..8f60d23ebe 100644 --- a/lib/codegen/src/lib.rs +++ b/lib/codegen/src/lib.rs @@ -41,6 +41,21 @@ use_self, ))] +// Turns on no_std and alloc features if std is not available. +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +// Include the `hashmap_core` crate if std is not available. +#[allow(unused_extern_crates)] +#[cfg(not(feature = "std"))] +extern crate hashmap_core; +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc; +extern crate failure; +#[macro_use] +extern crate failure_derive; + pub use context::Context; pub use legalizer::legalize_function; pub use verifier::verify_function; @@ -93,3 +108,15 @@ mod stack_layout; mod topo_order; mod unreachable_code; mod write; + +/// This replaces `std` in builds with `core`. +#[cfg(not(feature = "std"))] +mod std { + pub use core::*; + pub use alloc::{boxed, vec, string}; + pub mod collections { + pub use hashmap_core::{HashMap, HashSet}; + pub use hashmap_core::map as hash_map; + pub use alloc::BTreeSet; + } +} diff --git a/lib/codegen/src/print_errors.rs b/lib/codegen/src/print_errors.rs index 917f860ce9..ffc8bab4ec 100644 --- a/lib/codegen/src/print_errors.rs +++ b/lib/codegen/src/print_errors.rs @@ -4,6 +4,7 @@ use ir; use isa::TargetIsa; use result::CtonError; use std::fmt::Write; +use std::string::{String, ToString}; use verifier; /// Pretty-print a verifier error. diff --git a/lib/codegen/src/result.rs b/lib/codegen/src/result.rs index a762b48e1c..47047e2f4e 100644 --- a/lib/codegen/src/result.rs +++ b/lib/codegen/src/result.rs @@ -1,25 +1,28 @@ //! Result and error types representing the outcome of compiling a function. -use std::error::Error as StdError; -use std::fmt; use verifier; /// A compilation error. /// /// When Cretonne fails to compile a function, it will return one of these error codes. -#[derive(Debug, PartialEq, Eq)] +#[derive(Fail, Debug, PartialEq, Eq)] pub enum CtonError { /// The input is invalid. /// /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly /// code. This should never happen for validated WebAssembly code. + #[fail(display = "Invalid input code")] InvalidInput, /// An IR verifier error. /// /// This always represents a bug, either in the code that generated IR for Cretonne, or a bug /// in Cretonne itself. - Verifier(verifier::Error), + #[fail(display = "Verifier error: {}", _0)] + Verifier( + #[cause] + verifier::Error + ), /// An implementation limit was exceeded. /// @@ -27,48 +30,20 @@ pub enum CtonError { /// limits][limits] that cause compilation to fail when they are exceeded. /// /// [limits]: https://cretonne.readthedocs.io/en/latest/langref.html#implementation-limits + #[fail(display = "Implementation limit exceeded")] ImplLimitExceeded, /// The code size for the function is too large. /// /// Different target ISAs may impose a limit on the size of a compiled function. If that limit /// is exceeded, compilation fails. + #[fail(display = "Code for function is too large")] CodeTooLarge, } /// A Cretonne compilation result. pub type CtonResult = Result<(), CtonError>; -impl fmt::Display for CtonError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - CtonError::Verifier(ref e) => write!(f, "Verifier error: {}", e), - CtonError::InvalidInput | - CtonError::ImplLimitExceeded | - CtonError::CodeTooLarge => f.write_str(self.description()), - } - } -} - -impl StdError for CtonError { - fn description(&self) -> &str { - match *self { - CtonError::InvalidInput => "Invalid input code", - CtonError::Verifier(ref e) => &e.message, - CtonError::ImplLimitExceeded => "Implementation limit exceeded", - CtonError::CodeTooLarge => "Code for function is too large", - } - } - fn cause(&self) -> Option<&StdError> { - match *self { - CtonError::Verifier(ref e) => Some(e), - CtonError::InvalidInput | - CtonError::ImplLimitExceeded | - CtonError::CodeTooLarge => None, - } - } -} - impl From for CtonError { fn from(e: verifier::Error) -> Self { CtonError::Verifier(e) diff --git a/lib/codegen/src/timing.rs b/lib/codegen/src/timing.rs index 31ec64e548..82653458c0 100644 --- a/lib/codegen/src/timing.rs +++ b/lib/codegen/src/timing.rs @@ -94,7 +94,8 @@ impl fmt::Display for Pass { /// /// This whole module can be gated on a `cfg` feature to provide a dummy implementation for /// performance-sensitive builds or restricted environments. The dummy implementation must provide -/// `TimingToken` and `PassTimings` types and a `take_current` function. +/// `TimingToken` and `PassTimes` types and `take_current`, `add_to_current`, and `start_pass` funcs +#[cfg(feature = "std")] mod details { use super::{Pass, DESCRIPTIONS, NUM_PASSES}; use std::cell::{Cell, RefCell}; @@ -216,9 +217,31 @@ mod details { } } +/// Dummy `debug` implementation +#[cfg(not(feature = "std"))] +mod details { + use super::Pass; + /// Dummy `TimingToken` + pub struct TimingToken; + /// Dummy `PassTimes` + pub struct PassTimes; + /// Returns dummy `PassTimes` + pub fn take_current() -> PassTimes { + PassTimes + } + /// does nothing + pub fn add_to_current(_times: PassTimes) {} + + /// does nothing + pub(super) fn start_pass(_pass: Pass) -> TimingToken { + TimingToken + } +} + #[cfg(test)] mod test { use super::*; + use std::string::ToString; #[test] fn display() { diff --git a/lib/codegen/src/verifier/mod.rs b/lib/codegen/src/verifier/mod.rs index 66baa5fa91..6408b61977 100644 --- a/lib/codegen/src/verifier/mod.rs +++ b/lib/codegen/src/verifier/mod.rs @@ -70,7 +70,6 @@ use iterators::IteratorExtras; use settings::{Flags, FlagsOrIsa}; use std::cmp::Ordering; use std::collections::BTreeSet; -use std::error as std_error; use std::fmt::{self, Display, Formatter, Write}; use std::result; use std::string::String; @@ -104,7 +103,7 @@ mod liveness; mod locations; /// A verifier error. -#[derive(Debug, PartialEq, Eq)] +#[derive(Fail, Debug, PartialEq, Eq)] pub struct Error { /// The entity causing the verifier error. pub location: AnyEntity, @@ -118,12 +117,6 @@ impl Display for Error { } } -impl std_error::Error for Error { - fn description(&self) -> &str { - &self.message - } -} - /// Verifier result. pub type Result = result::Result<(), Error>; @@ -1166,10 +1159,13 @@ mod tests { Ok(_) => panic!("Expected an error"), Err(Error { message, .. }) => { if !message.contains($msg) { + #[cfg(feature = "std")] panic!(format!( "'{}' did not contain the substring '{}'", message, $msg )); + #[cfg(not(feature = "std"))] + panic!("error message did not contain the expected substring"); } } } diff --git a/lib/frontend/Cargo.toml b/lib/frontend/Cargo.toml index 95d4a18786..68a4f3b817 100644 --- a/lib/frontend/Cargo.toml +++ b/lib/frontend/Cargo.toml @@ -9,7 +9,12 @@ repository = "https://github.com/cretonne/cretonne" readme = "README.md" [dependencies] -cretonne-codegen = { path = "../codegen", version = "0.5.1" } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } + +[features] +default = ["std"] +std = ["cretonne-codegen/std"] +core = ["cretonne-codegen/core"] [badges] maintenance = { status = "experimental" } diff --git a/lib/frontend/src/lib.rs b/lib/frontend/src/lib.rs index 77bb7ff6e6..494fecb414 100644 --- a/lib/frontend/src/lib.rs +++ b/lib/frontend/src/lib.rs @@ -140,12 +140,23 @@ unicode_not_nfc, use_self, ))] +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] extern crate cretonne_codegen; +#[cfg(not(feature = "std"))] +extern crate alloc; + pub use frontend::{FunctionBuilder, FunctionBuilderContext}; pub use variable::Variable; mod frontend; mod ssa; mod variable; + +#[cfg(not(feature = "std"))] +mod std { + pub use alloc::vec; + pub use core::*; +} diff --git a/lib/frontend/src/ssa.rs b/lib/frontend/src/ssa.rs index 1f95316b3c..9c07730de9 100644 --- a/lib/frontend/src/ssa.rs +++ b/lib/frontend/src/ssa.rs @@ -1024,7 +1024,12 @@ mod tests { let flags = settings::Flags::new(&settings::builder()); match verify_function(&func, &flags) { Ok(()) => {} - Err(err) => panic!(err.message), + Err(err) => { + #[cfg(feature = "std")] + panic!(err.message); + #[cfg(not(feature = "std"))] + panic!("function failed to verify"); + } } } @@ -1198,7 +1203,12 @@ mod tests { let flags = settings::Flags::new(&settings::builder()); match verify_function(&func, &flags) { Ok(()) => {} - Err(err) => panic!(err.message), + Err(err) => { + #[cfg(feature = "std")] + panic!(err.message); + #[cfg(not(feature = "std"))] + panic!("function failed to verify"); + } } } @@ -1244,7 +1254,12 @@ mod tests { let flags = settings::Flags::new(&settings::builder()); match verify_function(&func, &flags) { Ok(()) => {} - Err(err) => panic!(err.message), + Err(err) => { + #[cfg(feature = "std")] + panic!(err.message); + #[cfg(not(feature = "std"))] + panic!("function failed to verify"); + } } } } diff --git a/lib/module/Cargo.toml b/lib/module/Cargo.toml index e2b2aa30c5..defbb016d8 100644 --- a/lib/module/Cargo.toml +++ b/lib/module/Cargo.toml @@ -9,8 +9,17 @@ license = "Apache-2.0" readme = "README.md" [dependencies] -cretonne-codegen = { path = "../codegen", version = "0.5.1" } -cretonne-entity = { path = "../entity", version = "0.5.1" } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } +cretonne-entity = { path = "../entity", version = "0.5.1", default-features = false } + +[dependencies.hashmap_core] +version = "0.1.1" +optional = true + +[features] +default = ["std"] +std = ["cretonne-codegen/std", "cretonne-entity/std"] +core = ["hashmap_core", "cretonne-codegen/core"] [badges] maintenance = { status = "experimental" } diff --git a/lib/native/Cargo.toml b/lib/native/Cargo.toml index 79fc6e7b6c..38ed8cef48 100644 --- a/lib/native/Cargo.toml +++ b/lib/native/Cargo.toml @@ -8,11 +8,16 @@ license = "Apache-2.0" readme = "README.md" [dependencies] -cretonne-codegen = { path = "../codegen", version = "0.5.1" } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } [target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies] raw-cpuid = "3.1.0" +[features] +default = ["std"] +std = ["cretonne-codegen/std"] +core = ["cretonne-codegen/core"] + [badges] maintenance = { status = "experimental" } travis-ci = { repository = "cretonne/cretonne" } diff --git a/lib/native/src/lib.rs b/lib/native/src/lib.rs index 847ec55af1..e84be550e2 100644 --- a/lib/native/src/lib.rs +++ b/lib/native/src/lib.rs @@ -16,9 +16,9 @@ unicode_not_nfc, use_self, ))] +#![cfg_attr(not(feature = "std"), no_std)] extern crate cretonne_codegen; - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] extern crate raw_cpuid; diff --git a/lib/simplejit/Cargo.toml b/lib/simplejit/Cargo.toml index b45890450d..e914206a74 100644 --- a/lib/simplejit/Cargo.toml +++ b/lib/simplejit/Cargo.toml @@ -9,13 +9,18 @@ license = "Apache-2.0" readme = "README.md" [dependencies] -cretonne-codegen = { path = "../codegen", version = "0.5.1" } -cretonne-module = { path = "../module", version = "0.5.1" } -cretonne-native = { path = "../native", version = "0.5.1" } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } +cretonne-module = { path = "../module", version = "0.5.1", default-features = false } +cretonne-native = { path = "../native", version = "0.5.1", default-features = false } region = "0.2.0" -libc = "0.2.40" +libc = { version = "0.2.40", default-features = false } errno = "0.2.3" +[features] +default = ["std"] +std = ["libc/use_std", "cretonne-codegen/std", "cretonne-module/std", "cretonne-native/std"] +core = ["cretonne-codegen/core", "cretonne-module/core", "cretonne-native/core"] + [badges] maintenance = { status = "experimental" } travis-ci = { repository = "Cretonne/cretonne" } diff --git a/lib/umbrella/Cargo.toml b/lib/umbrella/Cargo.toml index f7bdc002cd..6895955244 100644 --- a/lib/umbrella/Cargo.toml +++ b/lib/umbrella/Cargo.toml @@ -10,8 +10,13 @@ readme = "README.md" keywords = ["compile", "compiler", "jit"] [dependencies] -cretonne-codegen = { path = "../codegen", version = "0.5.1" } -cretonne-frontend = { path = "../frontend", version = "0.5.1" } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } +cretonne-frontend = { path = "../frontend", version = "0.5.1", default-features = false } + +[features] +default = ["std"] +std = ["cretonne-codegen/std", "cretonne-frontend/std"] +core = ["cretonne-codegen/core", "cretonne-frontend/core"] [badges] maintenance = { status = "experimental" } diff --git a/lib/wasm/Cargo.toml b/lib/wasm/Cargo.toml index a0809a5360..7c83cf9ed8 100644 --- a/lib/wasm/Cargo.toml +++ b/lib/wasm/Cargo.toml @@ -9,13 +9,22 @@ readme = "README.md" keywords = ["webassembly", "wasm"] [dependencies] -wasmparser = "0.15.1" -cretonne-codegen = { path = "../codegen", version = "0.5.1" } -cretonne-frontend = { path = "../frontend", version = "0.5.1" } +wasmparser = { version = "0.16.0", default-features = false } +cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false } +cretonne-frontend = { path = "../frontend", version = "0.5.1", default-features = false } + +[dependencies.hashmap_core] +version = "0.1.1" +optional = true [dev-dependencies] tempdir = "0.3.5" +[features] +default = ["std"] +std = ["cretonne-codegen/std", "cretonne-frontend/std", "wasmparser/std"] +core = ["hashmap_core", "cretonne-codegen/core", "cretonne-frontend/core", "wasmparser/core"] + [badges] maintenance = { status = "experimental" } travis-ci = { repository = "cretonne/cretonne" } diff --git a/lib/wasm/src/environ/dummy.rs b/lib/wasm/src/environ/dummy.rs index e716927745..e04bd5f180 100644 --- a/lib/wasm/src/environ/dummy.rs +++ b/lib/wasm/src/environ/dummy.rs @@ -6,7 +6,6 @@ use cretonne_codegen::ir::{self, InstBuilder}; use cretonne_codegen::settings; use environ::{FuncEnvironment, GlobalValue, ModuleEnvironment}; use func_translator::FuncTranslator; -use std::error::Error; use std::string::String; use std::vec::Vec; use translation_utils::{FunctionIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, @@ -392,7 +391,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { let reader = wasmparser::BinaryReader::new(body_bytes); self.trans .translate_from_reader(reader, &mut func, &mut func_environ) - .map_err(|e| String::from(e.description()))?; + .map_err(|e| format!("{}", e))?; func }; self.func_bytecode_sizes.push(body_bytes.len()); diff --git a/lib/wasm/src/lib.rs b/lib/wasm/src/lib.rs index 5a2e24948b..b893e3b903 100644 --- a/lib/wasm/src/lib.rs +++ b/lib/wasm/src/lib.rs @@ -25,6 +25,17 @@ use_self, ))] +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc; + +#[allow(unused_extern_crates)] +#[cfg(not(feature = "std"))] +extern crate hashmap_core; + #[macro_use(dbg)] extern crate cretonne_codegen; extern crate cretonne_frontend; @@ -43,3 +54,13 @@ pub use func_translator::FuncTranslator; pub use module_translator::translate_module; pub use translation_utils::{FunctionIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex, Table, TableIndex}; + +#[cfg(not(feature = "std"))] +mod std { + pub use alloc::vec; + pub use alloc::string; + pub use core::{u32, i32, str, cmp}; + pub mod collections { + pub use hashmap_core::{HashMap, map as hash_map}; + } +}