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
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 <https://github.com/cretonne/cretonne/tree/no_std>`_.
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
--------------------------

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"
[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" }

View File

@@ -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<K, V, C>(PhantomData<(K, V, C)>);
@@ -207,14 +211,14 @@ where
#[cfg(test)]
impl<K, V, C> Map<K, V, C>
where
K: Copy + ::std::fmt::Display,
K: Copy + fmt::Display,
V: Copy,
C: Comparator<K>,
{
/// Verify consistency.
fn verify(&self, forest: &MapForest<K, V, C>, comp: &C)
where
NodeData<MapTypes<K, V, C>>: ::std::fmt::Display,
NodeData<MapTypes<K, V, C>>: 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<K, V, C>, 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<K>,
{
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()
}
}

View File

@@ -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<F: Forest> {
@@ -74,8 +76,8 @@ impl<F: Forest> NodePool<F> {
/// Verify the consistency of the tree rooted at `node`.
pub fn verify_tree(&self, node: Node, comp: &F::Comparator)
where
NodeData<F>: ::std::fmt::Display,
F::Key: ::std::fmt::Display,
NodeData<F>: fmt::Display,
F::Key: fmt::Display,
{
use super::Comparator;
use entity::SparseSet;

View File

@@ -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<K, C>(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<K>,
{
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()
}
}

View File

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

View File

@@ -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<io::BufWriter<File>> = 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<File> {
let curthread = thread::current();
let tmpstr;
@@ -90,6 +110,7 @@ fn open_file() -> io::BufWriter<File> {
/// 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

View File

@@ -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"
);
}

View File

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

View File

@@ -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;
}
}

View File

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

View File

@@ -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<verifier::Error> for CtonError {
fn from(e: verifier::Error) -> Self {
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
/// 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() {

View File

@@ -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");
}
}
}

View File

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

View File

@@ -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::*;
}

View File

@@ -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");
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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());

View File

@@ -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};
}
}