diff --git a/.travis.yml b/.travis.yml index 6227873..86d7a85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ -language: - - rust +language: rust +rust: + - nightly + - stable script: - - cargo build --release --verbose - - cargo test --verbose \ No newline at end of file + - cargo build --all --release --verbose + - cargo test --all --verbose + - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo build --no-default-features; fi diff --git a/Cargo.toml b/Cargo.toml index 78e86b5..77847a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,37 +8,20 @@ description = "Collection of command-line utilities and corresponding Rust api f keywords = ["wasm", "webassembly", "pwasm"] [dependencies] -parity-wasm = "0.27" -log = "0.3" -env_logger = "0.4" -lazy_static = "0.2" -clap = "2.24" -glob = "0.2" -byteorder = "1" +parity-wasm = { version = "0.30", default-features = false } +log = { version = "0.4", default-features = false } +byteorder = { version = "1", default-features = false } [dev-dependencies] tempdir = "0.3" wabt = "0.2" diff = "0.1.11" -[lib] +[features] +default = ["std"] +std = ["parity-wasm/std", "log/std", "byteorder/std"] -[[bin]] -name = "wasm-prune" -path = "prune/main.rs" - -[[bin]] -name = "wasm-ext" -path = "ext/main.rs" - -[[bin]] -name = "wasm-gas" -path = "gas/main.rs" - -[[bin]] -name = "wasm-build" -path = "build/main.rs" - -[[bin]] -name = "wasm-stack-height" -path = "stack_height/main.rs" +[workspace] +members = [ + "./cli", +] diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..89ba7ee --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "pwasm-utils-cli" +version = "0.1.5" +authors = ["Nikolay Volf ", "Sergey Pepyakin "] +license = "MIT/Apache-2.0" +readme = "README.md" +description = "Collection of command-line utilities and corresponding Rust api for producing pwasm-compatible executables" +keywords = ["wasm", "webassembly", "pwasm"] + +[lib] + +[[bin]] +name = "wasm-prune" +path = "prune/main.rs" + +[[bin]] +name = "wasm-ext" +path = "ext/main.rs" + +[[bin]] +name = "wasm-gas" +path = "gas/main.rs" + +[[bin]] +name = "wasm-build" +path = "build/main.rs" + +[[bin]] +name = "wasm-stack-height" +path = "stack_height/main.rs" + +[dependencies] +parity-wasm = "0.30" +pwasm-utils = { path = ".." } +glob = "0.2" +clap = "2.24" +log = "0.4" +env_logger = "0.5" +lazy_static = "1.0" + +[dev-dependencies] +tempdir = "0.3" diff --git a/build/main.rs b/cli/build/main.rs similarity index 99% rename from build/main.rs rename to cli/build/main.rs index 5bf79d8..ee78c2a 100644 --- a/build/main.rs +++ b/cli/build/main.rs @@ -4,6 +4,7 @@ extern crate glob; extern crate pwasm_utils as utils; extern crate clap; extern crate parity_wasm; +extern crate pwasm_utils_cli as logger; mod source; @@ -95,7 +96,7 @@ fn has_ctor(module: &elements::Module) -> bool { } fn do_main() -> Result<(), Error> { - utils::init_log(); + logger::init_log(); let matches = App::new("wasm-build") .arg(Arg::with_name("target") diff --git a/build/source.rs b/cli/build/source.rs similarity index 100% rename from build/source.rs rename to cli/build/source.rs diff --git a/ext/main.rs b/cli/ext/main.rs similarity index 89% rename from ext/main.rs rename to cli/ext/main.rs index ee6796a..02d8ba3 100644 --- a/ext/main.rs +++ b/cli/ext/main.rs @@ -1,11 +1,12 @@ extern crate parity_wasm; extern crate pwasm_utils as utils; +extern crate pwasm_utils_cli as logger; use std::env; fn main() { - utils::init_log(); + logger::init_log(); let args = env::args().collect::>(); if args.len() != 3 { diff --git a/gas/main.rs b/cli/gas/main.rs similarity index 90% rename from gas/main.rs rename to cli/gas/main.rs index 4c02bce..0e9139f 100644 --- a/gas/main.rs +++ b/cli/gas/main.rs @@ -1,11 +1,11 @@ extern crate parity_wasm; extern crate pwasm_utils as utils; +extern crate pwasm_utils_cli as logger; use std::env; fn main() { - - utils::init_log(); + logger::init_log(); let args = env::args().collect::>(); if args.len() != 3 { diff --git a/prune/main.rs b/cli/prune/main.rs similarity index 96% rename from prune/main.rs rename to cli/prune/main.rs index 16f3b3c..658e249 100644 --- a/prune/main.rs +++ b/cli/prune/main.rs @@ -1,11 +1,12 @@ extern crate parity_wasm; extern crate pwasm_utils as utils; +extern crate pwasm_utils_cli as logger; extern crate clap; use clap::{App, Arg}; fn main() { - utils::init_log(); + logger::init_log(); let matches = App::new("wasm-opt") .arg(Arg::with_name("input") diff --git a/cli/src/lib.rs b/cli/src/lib.rs new file mode 100644 index 0000000..eeaabb0 --- /dev/null +++ b/cli/src/lib.rs @@ -0,0 +1,27 @@ +#[macro_use] extern crate log; +#[macro_use] extern crate lazy_static; +extern crate env_logger; + +use std::env; +use log::LevelFilter; +use env_logger::Builder; + +lazy_static! { + static ref LOG_DUMMY: bool = { + let mut builder = Builder::new(); + builder.filter(None, LevelFilter::Info); + + if let Ok(log) = env::var("RUST_LOG") { + builder.parse(&log); + } + + builder.init(); + trace!("logger initialized"); + true + }; +} + +/// Intialize log with default settings +pub fn init_log() { + let _ = *LOG_DUMMY; +} diff --git a/stack_height/main.rs b/cli/stack_height/main.rs similarity index 91% rename from stack_height/main.rs rename to cli/stack_height/main.rs index 80b8122..774baee 100644 --- a/stack_height/main.rs +++ b/cli/stack_height/main.rs @@ -1,11 +1,12 @@ extern crate pwasm_utils as utils; extern crate parity_wasm; +extern crate pwasm_utils_cli as logger; use std::env; use utils::stack_height; fn main() { - utils::init_log(); + logger::init_log(); let args = env::args().collect::>(); if args.len() != 3 { diff --git a/src/ext.rs b/src/ext.rs index 24eec02..5983785 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -1,3 +1,7 @@ +use std::string::String; +use std::vec::Vec; +use std::borrow::ToOwned; + use parity_wasm::{elements, builder}; use optimizer::{import_section, export_section}; use byteorder::{LittleEndian, ByteOrder}; @@ -200,4 +204,4 @@ pub fn externalize( module -} \ No newline at end of file +} diff --git a/src/gas.rs b/src/gas.rs index 99bcc6b..730e703 100644 --- a/src/gas.rs +++ b/src/gas.rs @@ -1,3 +1,5 @@ +use std::vec::Vec; + use parity_wasm::{elements, builder}; use rules; diff --git a/src/lib.rs b/src/lib.rs index 8753ec7..f1dc516 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,13 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc; + extern crate parity_wasm; -extern crate env_logger; extern crate byteorder; #[macro_use] extern crate log; -#[macro_use] extern crate lazy_static; pub static CREATE_SYMBOL: &'static str = "deploy"; pub static CALL_SYMBOL: &'static str = "call"; @@ -13,7 +18,6 @@ pub mod rules; mod optimizer; mod gas; mod symbols; -mod logger; mod ext; mod pack; mod runtime_type; @@ -22,7 +26,16 @@ pub mod stack_height; pub use optimizer::{optimize, Error as OptimizerError}; pub use gas::inject_gas_counter; -pub use logger::init_log; pub use ext::{externalize, externalize_mem, underscore_funcs, ununderscore_funcs, shrink_unknown_stack}; pub use pack::{pack_instance, Error as PackingError}; pub use runtime_type::inject_runtime_type; + +#[cfg(not(feature = "std"))] +mod std { + pub use core::*; + pub use alloc::{vec, string, boxed, borrow}; + + pub mod collections { + pub use alloc::{BTreeMap, BTreeSet}; + } +} diff --git a/src/logger.rs b/src/logger.rs deleted file mode 100644 index b7e2af8..0000000 --- a/src/logger.rs +++ /dev/null @@ -1,26 +0,0 @@ -extern crate log; - -use std::env; -use log::LogLevelFilter; -use env_logger::LogBuilder; - -lazy_static! { - static ref LOG_DUMMY: bool = { - let mut builder = LogBuilder::new(); - builder.filter(None, LogLevelFilter::Info); - - if let Ok(log) = env::var("RUST_LOG") { - builder.parse(&log); - } - - if let Ok(_) = builder.init() { - trace!("logger initialized"); - } - true - }; -} - -/// Intialize log with default settings -pub fn init_log() { - let _ = *LOG_DUMMY; -} diff --git a/src/optimizer.rs b/src/optimizer.rs index 9d2f6bb..890aab0 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -1,4 +1,9 @@ -use std::collections::HashSet; +#[cfg(features = "std")] +use std::collections::{HashSet as Set}; +#[cfg(not(features = "std"))] +use std::collections::{BTreeSet as Set}; +use std::vec::Vec; + use parity_wasm::elements; use symbols::{Symbol, expand_symbols, push_code_symbols, resolve_function}; @@ -19,7 +24,7 @@ pub fn optimize( // which in turn compile in unused imports and leaves unused functions // Algo starts from the top, listing all items that should stay - let mut stay = HashSet::new(); + let mut stay = Set::new(); for (index, entry) in module.export_section().ok_or(Error::NoExportSection)?.entries().iter().enumerate() { if used_exports.iter().find(|e| **e == entry.field()).is_some() { stay.insert(Symbol::Export(index)); @@ -615,4 +620,4 @@ mod tests { } } -} \ No newline at end of file +} diff --git a/src/pack.rs b/src/pack.rs index 96e6746..e8a1096 100644 --- a/src/pack.rs +++ b/src/pack.rs @@ -1,4 +1,7 @@ use std::fmt; +use std::vec::Vec; +use std::borrow::ToOwned; + use parity_wasm::elements::{ self, Section, DataSection, Opcode, DataSegment, InitExpr, Internal, External, ImportCountType, @@ -224,7 +227,6 @@ mod test { use parity_wasm::builder; use super::*; use super::super::optimize; - use byteorder::{ByteOrder, LittleEndian}; fn test_packer(mut module: elements::Module) { let mut ctor_module = module.clone(); diff --git a/src/rules.rs b/src/rules.rs index 50d85cd..f5a254c 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -1,4 +1,8 @@ -use std::collections::HashMap; +#[cfg(features = "std")] +use std::collections::{HashMap as Map}; +#[cfg(not(features = "std"))] +use std::collections::{BTreeMap as Map}; + use parity_wasm::elements; pub struct UnknownInstruction; @@ -10,7 +14,7 @@ pub enum Metering { Fixed(u32), } -#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)] +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] pub enum InstructionType { Bit, Add, @@ -265,7 +269,7 @@ impl InstructionType { #[derive(Debug)] pub struct Set { regular: u32, - entries: HashMap, + entries: Map, grow: u32, } @@ -273,14 +277,14 @@ impl Default for Set { fn default() -> Self { Set { regular: 1, - entries: HashMap::new(), + entries: Map::new(), grow: 0, } } } impl Set { - pub fn new(regular: u32, entries: HashMap) -> Self { + pub fn new(regular: u32, entries: Map) -> Self { Set { regular: regular, entries: entries, grow: 0 } } diff --git a/src/stack_height/max_height.rs b/src/stack_height/max_height.rs index fc4ca50..3d55e69 100644 --- a/src/stack_height/max_height.rs +++ b/src/stack_height/max_height.rs @@ -1,3 +1,5 @@ +use std::vec::Vec; + use parity_wasm::elements::{self, BlockType, Type}; use super::{resolve_func_type, Error}; diff --git a/src/stack_height/mod.rs b/src/stack_height/mod.rs index 9502ff5..119dedc 100644 --- a/src/stack_height/mod.rs +++ b/src/stack_height/mod.rs @@ -48,6 +48,9 @@ //! between the frames. //! - upon entry into the function entire stack frame is allocated. +use std::string::String; +use std::vec::Vec; + use parity_wasm::elements::{self, Type}; use parity_wasm::builder; diff --git a/src/stack_height/thunk.rs b/src/stack_height/thunk.rs index be1d626..ea1354b 100644 --- a/src/stack_height/thunk.rs +++ b/src/stack_height/thunk.rs @@ -1,8 +1,12 @@ +#[cfg(features = "std")] +use std::collections::{HashMap as Map}; +#[cfg(not(features = "std"))] +use std::collections::{BTreeMap as Map}; +use std::vec::Vec; + use parity_wasm::elements::{self, FunctionType, Internal}; use parity_wasm::builder; -use std::collections::HashMap; - use super::{resolve_func_type, Context, Error}; struct Thunk { @@ -22,7 +26,7 @@ pub(crate) fn generate_thunks( // Function indicies which needs to generate thunks. let mut need_thunks: Vec = Vec::new(); - let mut replacement_map: HashMap = { + let mut replacement_map: Map = { let exports = module .export_section() .map(|es| es.entries()) @@ -42,7 +46,7 @@ pub(crate) fn generate_thunks( .cloned(); // Replacement map is at least export section size. - let mut replacement_map: HashMap = HashMap::new(); + let mut replacement_map: Map = Map::new(); for func_idx in exported_func_indicies.chain(table_func_indicies) { let callee_stack_cost = ctx.stack_cost(func_idx).ok_or_else(|| { diff --git a/src/symbols.rs b/src/symbols.rs index 3348f1e..4e778a8 100644 --- a/src/symbols.rs +++ b/src/symbols.rs @@ -1,7 +1,12 @@ -use parity_wasm::elements; -use std::collections::HashSet; +#[cfg(features = "std")] +use std::collections::{HashSet as Set}; +#[cfg(not(features = "std"))] +use std::collections::{BTreeSet as Set}; +use std::vec::Vec; -#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] +use parity_wasm::elements; + +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)] pub enum Symbol { Type(usize), Import(usize), @@ -63,19 +68,19 @@ pub fn push_code_symbols(module: &elements::Module, opcodes: &[elements::Opcode] dest.push(resolve_global(module, idx)) }, _ => { }, - } + } } } -pub fn expand_symbols(module: &elements::Module, set: &mut HashSet) { +pub fn expand_symbols(module: &elements::Module, set: &mut Set) { use self::Symbol::*; // symbols that were already processed - let mut stop: HashSet = HashSet::new(); + let mut stop: Set = Set::new(); let mut fringe = set.iter().cloned().collect::>(); loop { let next = match fringe.pop() { - Some(s) if stop.contains(&s) => { continue; } + Some(s) if stop.contains(&s) => { continue; } Some(s) => s, _ => { break; } }; @@ -86,7 +91,7 @@ pub fn expand_symbols(module: &elements::Module, set: &mut HashSet) { let entry = &module.export_section().expect("Export section to exist").entries()[idx]; match entry.internal() { &elements::Internal::Function(func_idx) => { - let symbol = resolve_function(module, func_idx); + let symbol = resolve_function(module, func_idx); if !stop.contains(&symbol) { fringe.push(symbol); } @@ -97,7 +102,7 @@ pub fn expand_symbols(module: &elements::Module, set: &mut HashSet) { if !stop.contains(&symbol) { fringe.push(symbol); } - set.insert(symbol); + set.insert(symbol); }, _ => {} } @@ -110,9 +115,9 @@ pub fn expand_symbols(module: &elements::Module, set: &mut HashSet) { if !stop.contains(&type_symbol) { fringe.push(type_symbol); } - set.insert(type_symbol); + set.insert(type_symbol); }, - _ => {} + _ => {} } }, Function(idx) => { @@ -142,11 +147,11 @@ pub fn expand_symbols(module: &elements::Module, set: &mut HashSet) { fringe.push(symbol); } set.insert(symbol); - } + } } _ => {} } stop.insert(next); } -} \ No newline at end of file +}