Skip to content

Commit

Permalink
Turn the debug feature into a macro.
Browse files Browse the repository at this point in the history
  • Loading branch information
aarlt committed Jun 12, 2019
1 parent af1783e commit df5a093
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 41 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ qimalloc = { version = "0.1", optional = true }
[features]
default = ["std", "wee_alloc"]
std = []
debug = []
experimental = []
eth2 = []
10 changes: 5 additions & 5 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand All @@ -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
81 changes: 64 additions & 17 deletions src/debug.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
};
}
125 changes: 107 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -58,7 +65,7 @@ mod utils;

pub mod types;

#[cfg(feature = "debug")]
#[macro_use]
pub mod debug;

#[cfg(feature = "experimental")]
Expand All @@ -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.
Expand Down Expand Up @@ -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);
}
}

0 comments on commit df5a093

Please sign in to comment.