From df5a0930ac153f195e7099e4609a52cbe6030aa2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Wed, 12 Jun 2019 15:49:37 -0400 Subject: [PATCH] Turn the debug feature into a macro. --- Cargo.toml | 1 - circle.yml | 10 ++--- src/debug.rs | 81 ++++++++++++++++++++++++++------- src/lib.rs | 125 +++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 176 insertions(+), 41 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dc575a9..c4839d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,5 @@ qimalloc = { version = "0.1", optional = true } [features] default = ["std", "wee_alloc"] std = [] -debug = [] experimental = [] eth2 = [] diff --git a/circle.yml b/circle.yml index fd9db58..d0cee20 100644 --- a/circle.yml +++ b/circle.yml @@ -19,7 +19,9 @@ jobs: cargo fmt --all -- --check - run: name: Test - command: cargo test --target=x86_64-unknown-linux-gnu + command: | + cargo test --target=x86_64-unknown-linux-gnu + cargo test --release --target=x86_64-unknown-linux-gnu - run: name: Build command: | @@ -34,11 +36,9 @@ jobs: cargo build --release --no-default-features --features wee_alloc cargo build --release --no-default-features --features qimalloc # different feature sets - cargo build --release --features debug - cargo build --release --no-default-features --features debug + cargo build --release --no-default-features cargo build --release --features experimental cargo build --release --no-default-features --features experimental - cargo build --release --features experimental,debug - cargo build --release --no-default-features --features experimental,debug + cargo build --release --features experimental cargo build --release --features eth2 cargo build --release --no-default-features --features eth2 diff --git a/src/debug.rs b/src/debug.rs index ae2e659..a22d10d 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,46 +1,93 @@ //! The native debug interface exposed to the ewasm contract. These functions are for testing //! purposes only. On a live VM, any bytecode trying to import these symbols will be rejected. -use crate::types::StorageKey; - /// The native interface for debugging functions. -mod native { +#[cfg(debug_assertions)] +pub mod native { extern "C" { pub fn debug_print32(value: u32); pub fn debug_print64(value: u64); pub fn debug_printMem(offset: *const u32, len: u32); pub fn debug_printMemHex(offset: *const u32, len: u32); - pub fn debug_printStorage(pathOffset: *const u32); - pub fn debug_printStorageHex(pathOffset: *const u32); + pub fn debug_printStorage(path_offset: *const u32); + pub fn debug_printStorageHex(path_offset: *const u32); } } +#[macro_export] /// Prints an unsigned 32-bit int. -pub fn print32(value: u32) { - unsafe { native::debug_print32(value) } +macro_rules! print32 { + ($value:expr) => { + #[cfg(debug_assertions)] + { + unsafe { $crate::debug::native::debug_print32($value) } + } + }; } +#[macro_export] /// Prints an unsigned 64-bit int. -pub fn print64(value: u64) { - unsafe { native::debug_print64(value) } +macro_rules! print64 { + ($value:expr) => { + #[cfg(debug_assertions)] + { + unsafe { $crate::debug::native::debug_print64($value) } + } + }; } +#[macro_export] /// Prints the contents of a slice. -pub fn print_mem(slice: &[u8]) { - unsafe { native::debug_printMem(slice.as_ptr() as *const u32, slice.len() as u32) } +macro_rules! print_mem { + ($slice:expr) => { + #[cfg(debug_assertions)] + { + unsafe { + $crate::debug::native::debug_printMem( + $slice.as_ptr() as *const u32, + $slice.len() as u32, + ) + } + } + }; } +#[macro_export] /// Prints the contents of a slice in hexadecimal format. -pub fn print_mem_hex(slice: &[u8]) { - unsafe { native::debug_printMemHex(slice.as_ptr() as *const u32, slice.len() as u32) } +macro_rules! print_mem_hex { + ($slice:expr) => { + #[cfg(debug_assertions)] + { + unsafe { + $crate::debug::native::debug_printMemHex( + $slice.as_ptr() as *const u32, + $slice.len() as u32, + ) + } + } + }; } +#[macro_export] /// Prints the value of a storage key. -pub fn print_storage(key: &StorageKey) { - unsafe { native::debug_printStorage(key.bytes.as_ptr() as *const u32) } +macro_rules! print_storage { + ($key:expr) => { + #[cfg(debug_assertions)] + { + unsafe { $crate::debug::native::debug_printStorage($key.bytes.as_ptr() as *const u32) } + } + }; } +#[macro_export] /// Prints the value of a storage key in hexadecimal format. -pub fn print_storage_hex(key: &StorageKey) { - unsafe { native::debug_printStorageHex(key.bytes.as_ptr() as *const u32) } +macro_rules! print_storage_hex { + ($key:expr) => { + #[cfg(debug_assertions)] + { + unsafe { + $crate::debug::native::debug_printStorageHex($key.bytes.as_ptr() as *const u32) + } + } + }; } diff --git a/src/lib.rs b/src/lib.rs index 9e7e48c..86193a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,13 @@ #[macro_use] extern crate cfg_if; +#[cfg(feature = "std")] +use std::vec::Vec; + +use types::*; +#[cfg(feature = "std")] +use utils::*; + cfg_if! { if #[cfg(feature = "wee_alloc")] { extern crate wee_alloc; @@ -58,7 +65,7 @@ mod utils; pub mod types; -#[cfg(feature = "debug")] +#[macro_use] pub mod debug; #[cfg(feature = "experimental")] @@ -70,30 +77,17 @@ pub mod eth2; #[cfg(not(feature = "std"))] pub mod convert; -#[cfg(feature = "std")] -use std::vec::Vec; - -use types::*; -#[cfg(feature = "std")] -use utils::*; - /// Re-export of all the basic features. pub mod prelude { - pub use crate::*; - - pub use crate::types::*; - + #[cfg(feature = "experimental")] + pub use crate::bignum; #[cfg(not(feature = "std"))] pub use crate::convert::*; - - #[cfg(feature = "debug")] pub use crate::debug; - - #[cfg(feature = "experimental")] - pub use crate::bignum; - #[cfg(feature = "eth2")] pub use crate::eth2; + pub use crate::types::*; + pub use crate::*; } /// Declare entry point for a contract. Expects a Rust function name to be executed. @@ -667,3 +661,98 @@ pub fn selfdestruct(address: &Address) -> ! { native::ethereum_selfDestruct(address.bytes.as_ptr() as *const u32); } } + +#[cfg(test)] +mod debug_macros { + use crate::types::StorageKey; + + #[cfg(debug_assertions)] + #[no_mangle] + pub fn debug_print32(_value: u32) {} + + #[cfg(debug_assertions)] + #[no_mangle] + pub fn debug_print64(_value: u64) {} + + #[cfg(debug_assertions)] + #[allow(non_snake_case)] + #[no_mangle] + pub fn debug_printMem(_offset: *const u32, _len: u32) {} + + #[cfg(debug_assertions)] + #[allow(non_snake_case)] + #[no_mangle] + pub fn debug_printMemHex(_offset: *const u32, _len: u32) {} + + #[cfg(debug_assertions)] + #[allow(non_snake_case)] + #[no_mangle] + pub fn debug_printStorage(_path_offset: *const u32) {} + + #[cfg(debug_assertions)] + #[allow(non_snake_case)] + #[no_mangle] + pub fn debug_printStorageHex(_path_offset: *const u32) {} + + #[test] + fn test_print32() { + let _v: u32 = 42; + print32!(_v); + print32!(42); + print32!(42 + 1); + } + + #[test] + fn test_print64() { + let _v: u64 = 4242; + print64!(_v); + print64!(4242); + print64!(4242 + 1); + } + + #[test] + fn test_print_mem() { + let _mem: [u8; 0] = []; + print_mem!(_mem); + let _mem: [u8; 3] = [0, 1, 2]; + print_mem!(_mem); + let _mem = [0, 1, 2, 3, 4, 5]; + print_mem!(_mem); + print_mem!([0, 1]); + } + + #[test] + fn test_print_mem_hex() { + let _mem: [u8; 0] = []; + print_mem_hex!(_mem); + let _mem: [u8; 3] = [0, 1, 2]; + print_mem_hex!(_mem); + let _mem = [0, 1, 2, 3, 4, 5]; + print_mem_hex!(_mem); + print_mem_hex!([0, 1]); + } + + #[test] + fn test_print_storage() { + let _key = StorageKey { + bytes: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], + }; + print_storage!(_key); + } + + #[test] + fn test_print_storage_hex() { + let _key = StorageKey { + bytes: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], + }; + print_storage_hex!(_key); + } +}