From c1ca0cf3e78a8df7950d829e213e22ae7acc9c7b Mon Sep 17 00:00:00 2001 From: Gav Date: Thu, 8 Feb 2018 11:10:34 +0100 Subject: [PATCH] Fix runtime error. --- substrate/Cargo.lock | 4 +- substrate/executor/src/wasm_executor.rs | 64 +++++++++++++++--- substrate/executor/wasm/Cargo.lock | 4 +- substrate/polkadot-executor/src/lib.rs | 11 +-- substrate/polkadot-runtime/src/genesismap.rs | 2 +- .../src/runtime/parachains.rs | 2 +- .../polkadot-runtime/src/runtime/staking.rs | 2 +- .../polkadot-runtime/src/runtime/system.rs | 19 +++++- .../src/support/environment.rs | 8 +-- substrate/polkadot-runtime/wasm/Cargo.lock | 26 +++---- substrate/polkadot-runtime/wasm/Cargo.toml | 2 +- substrate/polkadot-runtime/wasm/build.sh | 4 +- substrate/polkadot-runtime/wasm/genesis.wasm | Bin 0 -> 70449 bytes substrate/runtime-io/Cargo.toml | 2 - substrate/runtime-io/with_std.rs | 7 -- substrate/runtime-io/without_std.rs | 32 ++++----- substrate/runtime-std/Cargo.toml | 2 + substrate/runtime-std/without_std.rs | 5 ++ 18 files changed, 123 insertions(+), 73 deletions(-) create mode 100644 substrate/polkadot-runtime/wasm/genesis.wasm diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 2e3dc3238a..b2fca77787 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1490,8 +1490,6 @@ version = "0.1.0" dependencies = [ "ed25519 0.1.0", "environmental 0.1.0", - "pwasm-alloc 0.1.0", - "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-primitives 0.1.0", @@ -1504,6 +1502,8 @@ dependencies = [ name = "substrate-runtime-std" version = "0.1.0" dependencies = [ + "pwasm-alloc 0.1.0", + "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index beefb55ec1..7ba1dd5d2f 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -37,7 +37,7 @@ struct Heap { impl Heap { fn new() -> Self { Heap { - end: 32768, + end: 262144, } } fn allocate(&mut self, size: u32) -> u32 { @@ -53,6 +53,7 @@ struct FunctionExecutor<'e, E: Externalities + 'e> { heap: Heap, memory: Arc, ext: &'e mut E, + hash_lookup: HashMap, Vec>, } impl<'e, E: Externalities> FunctionExecutor<'e, E> { @@ -61,6 +62,7 @@ impl<'e, E: Externalities> FunctionExecutor<'e, E> { heap: Heap::new(), memory: Arc::clone(m), ext: e, + hash_lookup: HashMap::new(), } } } @@ -89,21 +91,39 @@ impl ReadPrimitive for MemoryInstance { } } +fn ascii_format(asciish: &[u8]) -> String { + let mut r = String::new(); + let mut latch = false; + for c in asciish { + match (latch, *c) { + (false, 32...127) => r.push(*c as char), + _ => { + if !latch { + r.push('#'); + latch = true; + } + r.push_str(&format!("{:02x}", *c)); + } + } + } + r +} + impl_function_executor!(this: FunctionExecutor<'e, E>, ext_print_utf8(utf8_data: *const u8, utf8_len: u32) => { if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { if let Ok(message) = String::from_utf8(utf8) { - info!(target: "runtime", "{}", message); + println!("{}", message); } } }, ext_print_hex(data: *const u8, len: u32) => { if let Ok(hex) = this.memory.get(data, len as usize) { - info!(target: "runtime", "{}", HexDisplay::from(&hex)); + println!("{}", HexDisplay::from(&hex)); } }, ext_print_num(number: u64) => { - info!(target: "runtime", "{}", number); + println!("{}", number); }, ext_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 => { let sl1 = this.memory.get(s1, n as usize).map_err(|_| DummyUserError)?; @@ -144,13 +164,23 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; let value = this.memory.get(value_data, value_len as usize).map_err(|_| DummyUserError)?; - info!(target: "runtime", "Setting storage: {} -> {}", HexDisplay::from(&key), HexDisplay::from(&value)); + if let Some(preimage) = this.hash_lookup.get(&key) { + println!("*** Setting storage: %{} -> {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); + } else { + println!("*** Setting storage: {} -> {} [k={}]", ascii_format(&key), HexDisplay::from(&value), HexDisplay::from(&key)); + } this.ext.set_storage(key, value); }, ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + if let Some(preimage) = this.hash_lookup.get(&key) { + println!(" Getting storage: %{} == {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); + } else { + println!(" Getting storage: {} == {} [k={}]", ascii_format(&key), HexDisplay::from(&value), HexDisplay::from(&key)); + } + let offset = this.heap.allocate(value.len() as u32) as u32; this.memory.set(offset, &value).map_err(|_| DummyUserError)?; @@ -160,7 +190,11 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32 => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; - info!(target: "runtime", "Getting storage: {} ( -> {})", HexDisplay::from(&key), HexDisplay::from(&value)); + if let Some(preimage) = this.hash_lookup.get(&key) { + println!(" Getting storage: %{} == {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); + } else { + println!(" Getting storage: {} == {} [k={}]", ascii_format(&key), HexDisplay::from(&value), HexDisplay::from(&key)); + } let value = &value[value_offset as usize..]; let written = ::std::cmp::min(value_len as usize, value.len()); this.memory.set(value_data, &value[..written]).map_err(|_| DummyUserError)?; @@ -189,18 +223,22 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }, ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { let result = if len == 0 { - info!(target: "runtime", "XXhash: ''"); - twox_128(&[0u8; 0]) + let hashed = twox_128(&[0u8; 0]); + //println!("XXhash: '' -> {}", HexDisplay::from(&hashed)); + this.hash_lookup.insert(hashed.to_vec(), vec![]); + hashed } else { let key = this.memory.get(data, len as usize).map_err(|_| DummyUserError)?; let hashed_key = twox_128(&key); if let Ok(skey) = ::std::str::from_utf8(&key) { - info!(target: "runtime", "XXhash: {} -> {}", skey, HexDisplay::from(&hashed_key)); + //println!("XXhash: {} -> {}", skey, HexDisplay::from(&hashed_key)); } else { - info!(target: "runtime", "XXhash: {} -> {}", HexDisplay::from(&key), HexDisplay::from(&hashed_key)); + //println!("XXhash: {} -> {}", HexDisplay::from(&key), HexDisplay::from(&hashed_key)); } + this.hash_lookup.insert(hashed_key.to_vec(), key); hashed_key }; + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { @@ -252,6 +290,7 @@ impl CodeExecutor for WasmExecutor { data: &[u8], ) -> Result> { // TODO: handle all expects as errors to be returned. + println!(/*target: "wasm-executor",*/ "Wasm-Calling {}({})", method, HexDisplay::from(&data)); let program = ProgramInstance::new().expect("this really shouldn't be able to fail; qed"); @@ -276,8 +315,11 @@ impl CodeExecutor for WasmExecutor { })?; if let Some(I64(r)) = returned { - memory.get(r as u32, (r >> 32) as u32 as usize) + let offset = r as u32; + let length = (r >> 32) as u32 as usize; + memory.get(offset, length) .map_err(|_| ErrorKind::Runtime.into()) + .map(|v| { println!(/*target: "wasm-executor",*/ "Returned {}", HexDisplay::from(&v)); v }) } else { Err(ErrorKind::InvalidReturn.into()) } diff --git a/substrate/executor/wasm/Cargo.lock b/substrate/executor/wasm/Cargo.lock index bed624c544..5b062eb2d9 100644 --- a/substrate/executor/wasm/Cargo.lock +++ b/substrate/executor/wasm/Cargo.lock @@ -88,8 +88,6 @@ dependencies = [ name = "substrate-runtime-io" version = "0.1.0" dependencies = [ - "pwasm-alloc 0.1.0", - "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-primitives 0.1.0", @@ -100,6 +98,8 @@ dependencies = [ name = "substrate-runtime-std" version = "0.1.0" dependencies = [ + "pwasm-alloc 0.1.0", + "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/polkadot-executor/src/lib.rs b/substrate/polkadot-executor/src/lib.rs index 8ed3deed71..0c6c0fb37e 100644 --- a/substrate/polkadot-executor/src/lib.rs +++ b/substrate/polkadot-executor/src/lib.rs @@ -26,6 +26,7 @@ extern crate substrate_primitives as primitives; extern crate polkadot_primitives as polkadot_primitives; extern crate ed25519; extern crate triehash; +#[cfg(test)] #[macro_use] extern crate hex_literal; @@ -39,7 +40,7 @@ impl NativeExecutionDispatch for LocalNativeExecutionDispatch { fn native_equivalent() -> &'static [u8] { // WARNING!!! This assumes that the runtime was built *before* the main project. Until we // get a proper build script, this must be strictly adhered to or things will go wrong. - include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm") + include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm") } fn dispatch(method: &str, data: &[u8]) -> Option> { @@ -66,8 +67,8 @@ mod tests { UncheckedTransaction, Function, AccountId}; use ed25519::Pair; - const BLOATY_CODE: &[u8] = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); - const COMPACT_CODE: &[u8] = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); + const BLOATY_CODE: &[u8] = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm"); + const COMPACT_CODE: &[u8] = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"); // TODO: move into own crate. macro_rules! map { @@ -288,7 +289,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let foreign_code = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); + let foreign_code = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm"); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); assert!(r.is_err()); } @@ -302,7 +303,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let foreign_code = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); + let foreign_code = include_bytes!("../../polkadot-runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); assert!(r.is_ok()); diff --git a/substrate/polkadot-runtime/src/genesismap.rs b/substrate/polkadot-runtime/src/genesismap.rs index df7fe04711..a12086cc47 100644 --- a/substrate/polkadot-runtime/src/genesismap.rs +++ b/substrate/polkadot-runtime/src/genesismap.rs @@ -50,7 +50,7 @@ impl GenesisConfig { } pub fn genesis_map(&self) -> HashMap, Vec> { - let wasm_runtime = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm").to_vec(); + let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec(); vec![ (&b"gov:apr"[..], vec![].join(&self.approval_ratio)), (&b"ses:len"[..], vec![].join(&self.session_length)), diff --git a/substrate/polkadot-runtime/src/runtime/parachains.rs b/substrate/polkadot-runtime/src/runtime/parachains.rs index 222448467a..d0c4f5c845 100644 --- a/substrate/polkadot-runtime/src/runtime/parachains.rs +++ b/substrate/polkadot-runtime/src/runtime/parachains.rs @@ -17,7 +17,7 @@ //! Main parachains logic. For now this is just the determination of which validators do what. use rstd::prelude::*; -use runtime_io::mem; +use rstd::mem; use codec::{Slicable, Joiner}; use support::{Hashable, with_env, storage}; use runtime::session; diff --git a/substrate/polkadot-runtime/src/runtime/staking.rs b/substrate/polkadot-runtime/src/runtime/staking.rs index d6d4065dc9..210c518146 100644 --- a/substrate/polkadot-runtime/src/runtime/staking.rs +++ b/substrate/polkadot-runtime/src/runtime/staking.rs @@ -17,7 +17,7 @@ //! Staking manager: Handles balances and periodically determines the best set of validators. use rstd::prelude::*; -use runtime_io::cell::RefCell; +use rstd::cell::RefCell; use runtime_io::print; use codec::KeyedVec; use support::{storage, StorageVec}; diff --git a/substrate/polkadot-runtime/src/runtime/system.rs b/substrate/polkadot-runtime/src/runtime/system.rs index 6eb6229470..a82d911ea9 100644 --- a/substrate/polkadot-runtime/src/runtime/system.rs +++ b/substrate/polkadot-runtime/src/runtime/system.rs @@ -18,7 +18,8 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{mem, storage_root, enumerated_trie_root}; +use rstd::mem; +use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; use support::{Hashable, storage, with_env}; use polkadot_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header, @@ -71,6 +72,7 @@ pub mod internal { // execute transactions block.transactions.iter().cloned().for_each(super::execute_transaction); + // post-transactional book-keeping. staking::internal::check_new_era(); session::internal::check_rotate_session(); @@ -103,6 +105,13 @@ pub mod internal { /// Finalise the block - it is up the caller to ensure that all header fields are valid /// except state-root. pub fn finalise_block(mut header: Header) -> Header { + // populate environment from header. + with_env(|e| { + e.block_number = header.number; + e.parent_hash = header.parent_hash; + mem::swap(&mut header.digest, &mut e.digest); + }); + staking::internal::check_new_era(); session::internal::check_rotate_session(); @@ -211,7 +220,13 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { } #[cfg(not(feature = "std"))] -fn info_expect_equal_hash(_given: &Hash, _expected: &Hash) {} +fn info_expect_equal_hash(given: &Hash, expected: &Hash) { + if given != expected { + print("Hash not equal"); + print(&given.0[..]); + print(&expected.0[..]); + } +} #[cfg(test)] mod tests { diff --git a/substrate/polkadot-runtime/src/support/environment.rs b/substrate/polkadot-runtime/src/support/environment.rs index 63ab4277d1..d7651c575a 100644 --- a/substrate/polkadot-runtime/src/support/environment.rs +++ b/substrate/polkadot-runtime/src/support/environment.rs @@ -16,10 +16,10 @@ //! Environment API: Allows certain information to be accessed throughout the runtime. -use runtime_io::boxed::Box; -use runtime_io::mem; -use runtime_io::cell::RefCell; -use runtime_io::rc::Rc; +use rstd::boxed::Box; +use rstd::mem; +use rstd::cell::RefCell; +use rstd::rc::Rc; use polkadot_primitives::{BlockNumber, Digest, Hash}; diff --git a/substrate/polkadot-runtime/wasm/Cargo.lock b/substrate/polkadot-runtime/wasm/Cargo.lock index 7656a5a670..506b138461 100644 --- a/substrate/polkadot-runtime/wasm/Cargo.lock +++ b/substrate/polkadot-runtime/wasm/Cargo.lock @@ -386,6 +386,17 @@ dependencies = [ "substrate-runtime-std 0.1.0", ] +[[package]] +name = "polkadot-runtime" +version = "0.1.0" +dependencies = [ + "polkadot-primitives 0.1.0", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", +] + [[package]] name = "proc-macro-hack" version = "0.4.0" @@ -510,17 +521,6 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "runtime-polkadot" -version = "0.1.0" -dependencies = [ - "polkadot-primitives 0.1.0", - "substrate-codec 0.1.0", - "substrate-primitives 0.1.0", - "substrate-runtime-io 0.1.0", - "substrate-runtime-std 0.1.0", -] - [[package]] name = "rustc-hex" version = "1.0.0" @@ -621,8 +621,6 @@ version = "0.1.0" dependencies = [ "ed25519 0.1.0", "environmental 0.1.0", - "pwasm-alloc 0.1.0", - "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-primitives 0.1.0", @@ -635,6 +633,8 @@ dependencies = [ name = "substrate-runtime-std" version = "0.1.0" dependencies = [ + "pwasm-alloc 0.1.0", + "pwasm-libc 0.1.0", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/polkadot-runtime/wasm/Cargo.toml b/substrate/polkadot-runtime/wasm/Cargo.toml index 96084ddbde..b606dd6d83 100644 --- a/substrate/polkadot-runtime/wasm/Cargo.toml +++ b/substrate/polkadot-runtime/wasm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "runtime-polkadot" +name = "polkadot-runtime" version = "0.1.0" authors = ["Parity Technologies "] diff --git a/substrate/polkadot-runtime/wasm/build.sh b/substrate/polkadot-runtime/wasm/build.sh index 2cc63b0775..d48d10a062 100755 --- a/substrate/polkadot-runtime/wasm/build.sh +++ b/substrate/polkadot-runtime/wasm/build.sh @@ -2,7 +2,7 @@ set -e cargo +nightly build --target=wasm32-unknown-unknown --release -for i in polkadot +for i in polkadot_runtime do - wasm-gc target/wasm32-unknown-unknown/release/runtime_$i.wasm target/wasm32-unknown-unknown/release/runtime_$i.compact.wasm + wasm-gc target/wasm32-unknown-unknown/release/$i.wasm target/wasm32-unknown-unknown/release/$i.compact.wasm done diff --git a/substrate/polkadot-runtime/wasm/genesis.wasm b/substrate/polkadot-runtime/wasm/genesis.wasm new file mode 100644 index 0000000000000000000000000000000000000000..91c7b475743cb7b9cbb48c6dcc162501fe9e43c0 GIT binary patch literal 70449 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. -#[cfg(feature = "nightly")] -extern crate alloc; - -#[cfg(feature = "nightly")] -extern crate pwasm_libc; -#[cfg(feature = "nightly")] -extern crate pwasm_alloc; - +extern crate substrate_runtime_std as rstd; extern crate substrate_primitives as primitives; -pub use alloc::vec; -pub use alloc::boxed; -pub use alloc::rc; -pub use core::mem; -pub use core::slice; -pub use core::cell; - -use alloc::vec::Vec; +use rstd::intrinsics; +use rstd::vec::Vec; +pub use rstd::{mem, slice}; #[lang = "panic_fmt"] #[no_mangle] @@ -40,7 +28,7 @@ pub extern fn panic_fmt(_fmt: ::core::fmt::Arguments, _file: &'static str, _line ext_print_utf8(_file.as_ptr() as *const u8, _file.len() as u32); ext_print_num(_line as u64); ext_print_num(_col as u64); - ::core::intrinsics::abort() + intrinsics::abort() } } @@ -83,7 +71,11 @@ pub fn set_storage(key: &[u8], value: &[u8]) { /// the number of bytes that the key in storage was. pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize { unsafe { - ext_get_storage_into(key.as_ptr(), key.len() as u32, value_out.as_mut_ptr(), value_out.len() as u32, value_offset as u32) as usize + ext_get_storage_into( + key.as_ptr(), key.len() as u32, + value_out.as_mut_ptr(), value_out.len() as u32, + value_offset as u32 + ) as usize } } @@ -200,7 +192,9 @@ macro_rules! impl_stubs { }; let output = super::$name(input); - output.as_ptr() as u64 + ((output.len() as u64) << 32) + let r = output.as_ptr() as u64 + ((output.len() as u64) << 32); + $crate::mem::forget(output); + r } )* } diff --git a/substrate/runtime-std/Cargo.toml b/substrate/runtime-std/Cargo.toml index e619a9b5d4..42745a0152 100644 --- a/substrate/runtime-std/Cargo.toml +++ b/substrate/runtime-std/Cargo.toml @@ -8,6 +8,8 @@ build = "build.rs" rustc_version = "0.2" [dependencies] +pwasm-alloc = { path = "../pwasm-alloc" } +pwasm-libc = { path = "../pwasm-libc" } [features] default = ["std"] diff --git a/substrate/runtime-std/without_std.rs b/substrate/runtime-std/without_std.rs index ea0f278d37..4aff3153ca 100644 --- a/substrate/runtime-std/without_std.rs +++ b/substrate/runtime-std/without_std.rs @@ -16,6 +16,10 @@ #[cfg(feature = "nightly")] extern crate alloc; +#[cfg(feature = "nightly")] +extern crate pwasm_libc; +#[cfg(feature = "nightly")] +extern crate pwasm_alloc; pub use alloc::vec; pub use alloc::boxed; @@ -26,3 +30,4 @@ pub use core::cell; pub use core::ops; pub use core::iter; pub use core::ptr; +pub use core::intrinsics;