Merge pull request #303 from sunfishcode/no_std_merge

Merge no_std into master
This commit is contained in:
Dan Gohman
2018-04-20 12:11:53 -07:00
committed by GitHub
26 changed files with 318 additions and 74 deletions

View File

@@ -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 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. 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 The core codegen crates have minimal dependencies, support
floating-point support. Support for `no_std` mode in the core codegen crates is `no_std <#building-with-no-std>`_ mode, and do not require any host
`in development <https://github.com/cretonne/cretonne/tree/no_std>`_. floating-point support.
Cretonne does not yet perform mitigations for Spectre or related security 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 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 WebAssembly tests. Tests requiring wat2wasm are ignored if the tool is not
installed. 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 Building the documentation
-------------------------- --------------------------

32
cranelift/test-no_std.sh Executable file
View File

@@ -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"

View File

@@ -11,12 +11,26 @@ keywords = ["compile", "compiler", "jit"]
build = "build.rs" build = "build.rs"
[dependencies] [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. # 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 # 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 # machine code. Integration tests that need external dependencies can be
# accomodated in `tests`. # 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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }
travis-ci = { repository = "cretonne/cretonne" } travis-ci = { repository = "cretonne/cretonne" }

View File

@@ -3,6 +3,10 @@
use super::{Comparator, Forest, Node, NodeData, NodePool, Path, INNER_SIZE}; use super::{Comparator, Forest, Node, NodeData, NodePool, Path, INNER_SIZE};
use packed_option::PackedOption; use packed_option::PackedOption;
use std::marker::PhantomData; use std::marker::PhantomData;
#[cfg(test)]
use std::fmt;
#[cfg(test)]
use std::string::String;
/// Tag type defining forest types for a map. /// Tag type defining forest types for a map.
struct MapTypes<K, V, C>(PhantomData<(K, V, C)>); struct MapTypes<K, V, C>(PhantomData<(K, V, C)>);
@@ -207,14 +211,14 @@ where
#[cfg(test)] #[cfg(test)]
impl<K, V, C> Map<K, V, C> impl<K, V, C> Map<K, V, C>
where where
K: Copy + ::std::fmt::Display, K: Copy + fmt::Display,
V: Copy, V: Copy,
C: Comparator<K>, C: Comparator<K>,
{ {
/// Verify consistency. /// Verify consistency.
fn verify(&self, forest: &MapForest<K, V, C>, comp: &C) fn verify(&self, forest: &MapForest<K, V, C>, comp: &C)
where where
NodeData<MapTypes<K, V, C>>: ::std::fmt::Display, NodeData<MapTypes<K, V, C>>: fmt::Display,
{ {
if let Some(root) = self.root.expand() { if let Some(root) = self.root.expand() {
forest.nodes.verify_tree(root, comp); forest.nodes.verify_tree(root, comp);
@@ -223,6 +227,7 @@ where
/// Get a text version of the path to `key`. /// Get a text version of the path to `key`.
fn tpath(&self, key: K, forest: &MapForest<K, V, C>, comp: &C) -> String { fn tpath(&self, key: K, forest: &MapForest<K, V, C>, comp: &C) -> String {
use std::string::ToString;
match self.root.expand() { match self.root.expand() {
None => "map(empty)".to_string(), None => "map(empty)".to_string(),
Some(root) => { Some(root) => {
@@ -405,8 +410,8 @@ where
#[cfg(test)] #[cfg(test)]
impl<'a, K, V, C> MapCursor<'a, K, V, C> impl<'a, K, V, C> MapCursor<'a, K, V, C>
where where
K: Copy + ::std::fmt::Display, K: Copy + fmt::Display,
V: Copy + ::std::fmt::Display, V: Copy + fmt::Display,
C: Comparator<K>, C: Comparator<K>,
{ {
fn verify(&self) { fn verify(&self) {
@@ -416,6 +421,7 @@ where
/// Get a text version of the path to the current position. /// Get a text version of the path to the current position.
fn tpath(&self) -> String { fn tpath(&self) -> String {
use std::string::ToString;
self.path.to_string() self.path.to_string()
} }
} }

View File

@@ -3,6 +3,8 @@
use super::{Forest, Node, NodeData}; use super::{Forest, Node, NodeData};
use entity::PrimaryMap; use entity::PrimaryMap;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
#[cfg(test)]
use std::fmt;
/// A pool of nodes, including a free list. /// A pool of nodes, including a free list.
pub(super) struct NodePool<F: Forest> { pub(super) struct NodePool<F: Forest> {
@@ -74,8 +76,8 @@ impl<F: Forest> NodePool<F> {
/// Verify the consistency of the tree rooted at `node`. /// Verify the consistency of the tree rooted at `node`.
pub fn verify_tree(&self, node: Node, comp: &F::Comparator) pub fn verify_tree(&self, node: Node, comp: &F::Comparator)
where where
NodeData<F>: ::std::fmt::Display, NodeData<F>: fmt::Display,
F::Key: ::std::fmt::Display, F::Key: fmt::Display,
{ {
use super::Comparator; use super::Comparator;
use entity::SparseSet; use entity::SparseSet;

View File

@@ -3,6 +3,10 @@
use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE}; use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE};
use packed_option::PackedOption; use packed_option::PackedOption;
use std::marker::PhantomData; use std::marker::PhantomData;
#[cfg(test)]
use std::fmt;
#[cfg(test)]
use std::string::String;
/// Tag type defining forest types for a set. /// Tag type defining forest types for a set.
struct SetTypes<K, C>(PhantomData<(K, C)>); struct SetTypes<K, C>(PhantomData<(K, C)>);
@@ -305,7 +309,7 @@ where
#[cfg(test)] #[cfg(test)]
impl<'a, K, C> SetCursor<'a, K, C> impl<'a, K, C> SetCursor<'a, K, C>
where where
K: Copy + ::std::fmt::Display, K: Copy + fmt::Display,
C: Comparator<K>, C: Comparator<K>,
{ {
fn verify(&self) { fn verify(&self) {
@@ -315,6 +319,7 @@ where
/// Get a text version of the path to the current position. /// Get a text version of the path to the current position.
fn tpath(&self) -> String { fn tpath(&self) -> String {
use std::string::ToString;
self.path.to_string() self.path.to_string()
} }
} }

View File

@@ -23,6 +23,7 @@ use preopt::do_preopt;
use regalloc; use regalloc;
use result::{CtonError, CtonResult}; use result::{CtonError, CtonResult};
use settings::{FlagsOrIsa, OptLevel}; use settings::{FlagsOrIsa, OptLevel};
use std::vec::Vec;
use simple_gvn::do_simple_gvn; use simple_gvn::do_simple_gvn;
use timing; use timing;
use unreachable_code::eliminate_unreachable_code; use unreachable_code::eliminate_unreachable_code;

View File

@@ -8,15 +8,23 @@
/// ///
/// The output will appear in files named `cretonne.dbg.*`, where the suffix is named after the /// The output will appear in files named `cretonne.dbg.*`, where the suffix is named after the
/// thread doing the logging. /// thread doing the logging.
#[cfg(feature = "std")]
use std::cell::RefCell; use std::cell::RefCell;
#[cfg(feature = "std")]
use std::env; use std::env;
#[cfg(feature = "std")]
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fmt; use std::fmt;
#[cfg(feature = "std")]
use std::fs::File; use std::fs::File;
#[cfg(feature = "std")]
use std::io::{self, Write}; use std::io::{self, Write};
#[cfg(feature = "std")]
use std::sync::atomic; use std::sync::atomic;
#[cfg(feature = "std")]
use std::thread; use std::thread;
#[cfg(feature = "std")]
static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT; static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
/// Is debug tracing enabled? /// Is debug tracing enabled?
@@ -25,6 +33,7 @@ static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
/// other than `0`. /// other than `0`.
/// ///
/// This inline function turns into a constant `false` when debug assertions are disabled. /// This inline function turns into a constant `false` when debug assertions are disabled.
#[cfg(feature = "std")]
#[inline] #[inline]
pub fn enabled() -> bool { pub fn enabled() -> bool {
if cfg!(debug_assertions) { 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. /// Initialize `STATE` from the environment variable.
#[cfg(feature = "std")]
fn initialize() -> bool { fn initialize() -> bool {
let enable = match env::var_os("CRETONNE_DBG") { let enable = match env::var_os("CRETONNE_DBG") {
Some(s) => s != OsStr::new("0"), Some(s) => s != OsStr::new("0"),
@@ -53,6 +70,7 @@ fn initialize() -> bool {
enable enable
} }
#[cfg(feature = "std")]
thread_local! { thread_local! {
static WRITER : RefCell<io::BufWriter<File>> = RefCell::new(open_file()); static WRITER : RefCell<io::BufWriter<File>> = RefCell::new(open_file());
} }
@@ -60,6 +78,7 @@ thread_local! {
/// Write a line with the given format arguments. /// Write a line with the given format arguments.
/// ///
/// This is for use by the `dbg!` macro. /// This is for use by the `dbg!` macro.
#[cfg(feature = "std")]
pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> { pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> {
WRITER.with(|rc| { WRITER.with(|rc| {
let mut w = rc.borrow_mut(); 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. /// Open the tracing file for the current thread.
#[cfg(feature = "std")]
fn open_file() -> io::BufWriter<File> { fn open_file() -> io::BufWriter<File> {
let curthread = thread::current(); let curthread = thread::current();
let tmpstr; let tmpstr;
@@ -90,6 +110,7 @@ fn open_file() -> io::BufWriter<File> {
/// Write a line to the debug trace file if tracing is enabled. /// Write a line to the debug trace file if tracing is enabled.
/// ///
/// Arguments are the same as for `printf!`. /// Arguments are the same as for `printf!`.
#[cfg(feature = "std")]
#[macro_export] #[macro_export]
macro_rules! dbg { macro_rules! dbg {
($($arg:tt)+) => { ($($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. /// Helper for printing lists.
pub struct DisplayList<'a, T>(pub &'a [T]) pub struct DisplayList<'a, T>(pub &'a [T])
where where

View File

@@ -121,6 +121,7 @@ mod tests {
use super::ExternalName; use super::ExternalName;
use ir::LibCall; use ir::LibCall;
use std::string::ToString; use std::string::ToString;
use std::u32;
#[test] #[test]
fn display_testcase() { fn display_testcase() {
@@ -143,7 +144,7 @@ mod tests {
assert_eq!(ExternalName::user(0, 0).to_string(), "u0:0"); assert_eq!(ExternalName::user(0, 0).to_string(), "u0:0");
assert_eq!(ExternalName::user(1, 1).to_string(), "u1:1"); assert_eq!(ExternalName::user(1, 1).to_string(), "u1:1");
assert_eq!( assert_eq!(
ExternalName::user(::std::u32::MAX, ::std::u32::MAX).to_string(), ExternalName::user(u32::MAX, u32::MAX).to_string(),
"u4294967295:4294967295" "u4294967295:4294967295"
); );
} }

View File

@@ -2,6 +2,7 @@
use ir; use ir;
use ir::InstBuilder; use ir::InstBuilder;
use std::vec::Vec;
/// Try to expand `inst` as a library call, returning true is successful. /// 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 { pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function) -> bool {

View File

@@ -41,6 +41,21 @@
use_self, 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 context::Context;
pub use legalizer::legalize_function; pub use legalizer::legalize_function;
pub use verifier::verify_function; pub use verifier::verify_function;
@@ -93,3 +108,15 @@ mod stack_layout;
mod topo_order; mod topo_order;
mod unreachable_code; mod unreachable_code;
mod write; 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;
}
}

View File

@@ -4,6 +4,7 @@ use ir;
use isa::TargetIsa; use isa::TargetIsa;
use result::CtonError; use result::CtonError;
use std::fmt::Write; use std::fmt::Write;
use std::string::{String, ToString};
use verifier; use verifier;
/// Pretty-print a verifier error. /// Pretty-print a verifier error.

View File

@@ -1,25 +1,28 @@
//! Result and error types representing the outcome of compiling a function. //! Result and error types representing the outcome of compiling a function.
use std::error::Error as StdError;
use std::fmt;
use verifier; use verifier;
/// A compilation error. /// A compilation error.
/// ///
/// When Cretonne fails to compile a function, it will return one of these error codes. /// 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 { pub enum CtonError {
/// The input is invalid. /// The input is invalid.
/// ///
/// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
/// code. This should never happen for validated WebAssembly code. /// code. This should never happen for validated WebAssembly code.
#[fail(display = "Invalid input code")]
InvalidInput, InvalidInput,
/// An IR verifier error. /// An IR verifier error.
/// ///
/// This always represents a bug, either in the code that generated IR for Cretonne, or a bug /// This always represents a bug, either in the code that generated IR for Cretonne, or a bug
/// in Cretonne itself. /// in Cretonne itself.
Verifier(verifier::Error), #[fail(display = "Verifier error: {}", _0)]
Verifier(
#[cause]
verifier::Error
),
/// An implementation limit was exceeded. /// An implementation limit was exceeded.
/// ///
@@ -27,48 +30,20 @@ pub enum CtonError {
/// limits][limits] that cause compilation to fail when they are exceeded. /// limits][limits] that cause compilation to fail when they are exceeded.
/// ///
/// [limits]: https://cretonne.readthedocs.io/en/latest/langref.html#implementation-limits /// [limits]: https://cretonne.readthedocs.io/en/latest/langref.html#implementation-limits
#[fail(display = "Implementation limit exceeded")]
ImplLimitExceeded, ImplLimitExceeded,
/// The code size for the function is too large. /// 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 /// Different target ISAs may impose a limit on the size of a compiled function. If that limit
/// is exceeded, compilation fails. /// is exceeded, compilation fails.
#[fail(display = "Code for function is too large")]
CodeTooLarge, CodeTooLarge,
} }
/// A Cretonne compilation result. /// A Cretonne compilation result.
pub type CtonResult = Result<(), CtonError>; 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<verifier::Error> for CtonError { impl From<verifier::Error> for CtonError {
fn from(e: verifier::Error) -> Self { fn from(e: verifier::Error) -> Self {
CtonError::Verifier(e) CtonError::Verifier(e)

View File

@@ -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 /// 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 /// 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 { mod details {
use super::{Pass, DESCRIPTIONS, NUM_PASSES}; use super::{Pass, DESCRIPTIONS, NUM_PASSES};
use std::cell::{Cell, RefCell}; 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)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use std::string::ToString;
#[test] #[test]
fn display() { fn display() {

View File

@@ -70,7 +70,6 @@ use iterators::IteratorExtras;
use settings::{Flags, FlagsOrIsa}; use settings::{Flags, FlagsOrIsa};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::error as std_error;
use std::fmt::{self, Display, Formatter, Write}; use std::fmt::{self, Display, Formatter, Write};
use std::result; use std::result;
use std::string::String; use std::string::String;
@@ -104,7 +103,7 @@ mod liveness;
mod locations; mod locations;
/// A verifier error. /// A verifier error.
#[derive(Debug, PartialEq, Eq)] #[derive(Fail, Debug, PartialEq, Eq)]
pub struct Error { pub struct Error {
/// The entity causing the verifier error. /// The entity causing the verifier error.
pub location: AnyEntity, 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. /// Verifier result.
pub type Result = result::Result<(), Error>; pub type Result = result::Result<(), Error>;
@@ -1166,10 +1159,13 @@ mod tests {
Ok(_) => panic!("Expected an error"), Ok(_) => panic!("Expected an error"),
Err(Error { message, .. }) => { Err(Error { message, .. }) => {
if !message.contains($msg) { if !message.contains($msg) {
#[cfg(feature = "std")]
panic!(format!( panic!(format!(
"'{}' did not contain the substring '{}'", "'{}' did not contain the substring '{}'",
message, $msg message, $msg
)); ));
#[cfg(not(feature = "std"))]
panic!("error message did not contain the expected substring");
} }
} }
} }

View File

@@ -9,7 +9,12 @@ repository = "https://github.com/cretonne/cretonne"
readme = "README.md" readme = "README.md"
[dependencies] [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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }

View File

@@ -140,12 +140,23 @@
unicode_not_nfc, unicode_not_nfc,
use_self, use_self,
))] ))]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
extern crate cretonne_codegen; extern crate cretonne_codegen;
#[cfg(not(feature = "std"))]
extern crate alloc;
pub use frontend::{FunctionBuilder, FunctionBuilderContext}; pub use frontend::{FunctionBuilder, FunctionBuilderContext};
pub use variable::Variable; pub use variable::Variable;
mod frontend; mod frontend;
mod ssa; mod ssa;
mod variable; mod variable;
#[cfg(not(feature = "std"))]
mod std {
pub use alloc::vec;
pub use core::*;
}

View File

@@ -1024,7 +1024,12 @@ mod tests {
let flags = settings::Flags::new(&settings::builder()); let flags = settings::Flags::new(&settings::builder());
match verify_function(&func, &flags) { match verify_function(&func, &flags) {
Ok(()) => {} 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()); let flags = settings::Flags::new(&settings::builder());
match verify_function(&func, &flags) { match verify_function(&func, &flags) {
Ok(()) => {} 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()); let flags = settings::Flags::new(&settings::builder());
match verify_function(&func, &flags) { match verify_function(&func, &flags) {
Ok(()) => {} Ok(()) => {}
Err(err) => panic!(err.message), Err(err) => {
#[cfg(feature = "std")]
panic!(err.message);
#[cfg(not(feature = "std"))]
panic!("function failed to verify");
}
} }
} }
} }

View File

@@ -9,8 +9,17 @@ license = "Apache-2.0"
readme = "README.md" readme = "README.md"
[dependencies] [dependencies]
cretonne-codegen = { path = "../codegen", version = "0.5.1" } cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false }
cretonne-entity = { path = "../entity", version = "0.5.1" } 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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }

View File

@@ -8,11 +8,16 @@ license = "Apache-2.0"
readme = "README.md" readme = "README.md"
[dependencies] [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] [target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
raw-cpuid = "3.1.0" raw-cpuid = "3.1.0"
[features]
default = ["std"]
std = ["cretonne-codegen/std"]
core = ["cretonne-codegen/core"]
[badges] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }
travis-ci = { repository = "cretonne/cretonne" } travis-ci = { repository = "cretonne/cretonne" }

View File

@@ -16,9 +16,9 @@
unicode_not_nfc, unicode_not_nfc,
use_self, use_self,
))] ))]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate cretonne_codegen; extern crate cretonne_codegen;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
extern crate raw_cpuid; extern crate raw_cpuid;

View File

@@ -9,13 +9,18 @@ license = "Apache-2.0"
readme = "README.md" readme = "README.md"
[dependencies] [dependencies]
cretonne-codegen = { path = "../codegen", version = "0.5.1" } cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false }
cretonne-module = { path = "../module", version = "0.5.1" } cretonne-module = { path = "../module", version = "0.5.1", default-features = false }
cretonne-native = { path = "../native", version = "0.5.1" } cretonne-native = { path = "../native", version = "0.5.1", default-features = false }
region = "0.2.0" region = "0.2.0"
libc = "0.2.40" libc = { version = "0.2.40", default-features = false }
errno = "0.2.3" 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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }
travis-ci = { repository = "Cretonne/cretonne" } travis-ci = { repository = "Cretonne/cretonne" }

View File

@@ -10,8 +10,13 @@ readme = "README.md"
keywords = ["compile", "compiler", "jit"] keywords = ["compile", "compiler", "jit"]
[dependencies] [dependencies]
cretonne-codegen = { path = "../codegen", version = "0.5.1" } cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false }
cretonne-frontend = { path = "../frontend", version = "0.5.1" } 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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }

View File

@@ -9,13 +9,22 @@ readme = "README.md"
keywords = ["webassembly", "wasm"] keywords = ["webassembly", "wasm"]
[dependencies] [dependencies]
wasmparser = "0.15.1" wasmparser = { version = "0.16.0", default-features = false }
cretonne-codegen = { path = "../codegen", version = "0.5.1" } cretonne-codegen = { path = "../codegen", version = "0.5.1", default-features = false }
cretonne-frontend = { path = "../frontend", version = "0.5.1" } cretonne-frontend = { path = "../frontend", version = "0.5.1", default-features = false }
[dependencies.hashmap_core]
version = "0.1.1"
optional = true
[dev-dependencies] [dev-dependencies]
tempdir = "0.3.5" 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] [badges]
maintenance = { status = "experimental" } maintenance = { status = "experimental" }
travis-ci = { repository = "cretonne/cretonne" } travis-ci = { repository = "cretonne/cretonne" }

View File

@@ -6,7 +6,6 @@ use cretonne_codegen::ir::{self, InstBuilder};
use cretonne_codegen::settings; use cretonne_codegen::settings;
use environ::{FuncEnvironment, GlobalValue, ModuleEnvironment}; use environ::{FuncEnvironment, GlobalValue, ModuleEnvironment};
use func_translator::FuncTranslator; use func_translator::FuncTranslator;
use std::error::Error;
use std::string::String; use std::string::String;
use std::vec::Vec; use std::vec::Vec;
use translation_utils::{FunctionIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, 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); let reader = wasmparser::BinaryReader::new(body_bytes);
self.trans self.trans
.translate_from_reader(reader, &mut func, &mut func_environ) .translate_from_reader(reader, &mut func, &mut func_environ)
.map_err(|e| String::from(e.description()))?; .map_err(|e| format!("{}", e))?;
func func
}; };
self.func_bytecode_sizes.push(body_bytes.len()); self.func_bytecode_sizes.push(body_bytes.len());

View File

@@ -25,6 +25,17 @@
use_self, 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)] #[macro_use(dbg)]
extern crate cretonne_codegen; extern crate cretonne_codegen;
extern crate cretonne_frontend; extern crate cretonne_frontend;
@@ -43,3 +54,13 @@ pub use func_translator::FuncTranslator;
pub use module_translator::translate_module; pub use module_translator::translate_module;
pub use translation_utils::{FunctionIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, pub use translation_utils::{FunctionIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex,
SignatureIndex, Table, TableIndex}; 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};
}
}