Merge pull request #303 from sunfishcode/no_std_merge
Merge no_std into master
This commit is contained in:
54
README.rst
54
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
|
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
32
cranelift/test-no_std.sh
Executable 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"
|
||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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::*;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user