From d0a753587b5e4c2fc1c82a90ee86d2b5de426a6f Mon Sep 17 00:00:00 2001 From: clearloop <26088946+clearloop@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:38:04 -0500 Subject: [PATCH] feat(codegen): implement all log APIs (#125) * refactor(zink): remove size in log API * refactor(codegen): wrap dataset with extra methods * feat(codegen): support log1 * refactor(codegen): introduce new log parser * feat(compiler): tests for log3 and log4 --- codegen/src/asm.rs | 4 +- codegen/src/data.rs | 43 ++++++++++++++++++++ codegen/src/func.rs | 35 ++++++++++++---- codegen/src/lib.rs | 10 +---- codegen/src/result.rs | 5 ++- codegen/src/visitor/call.rs | 11 ++++- codegen/src/visitor/log.rs | 54 ++++++++++++++++--------- compiler/tests/log.rs | 80 +++++++++++++++++++++++++++++++++++++ compiler/wat/log/log0.wat | 12 +++--- compiler/wat/log/log1.wat | 17 ++++++++ compiler/wat/log/log2.wat | 19 +++++++++ compiler/wat/log/log3.wat | 21 ++++++++++ compiler/wat/log/log4.wat | 23 +++++++++++ examples/log/src/lib.rs | 29 ++++++++++---- examples/storage/src/lib.rs | 10 ++--- zink/src/event.rs | 53 +++++++++++++----------- zink/src/ffi/evm.rs | 29 ++++++++------ zink/src/ffi/memory.rs | 10 ----- zink/src/ffi/mod.rs | 1 - 19 files changed, 363 insertions(+), 103 deletions(-) create mode 100644 codegen/src/data.rs create mode 100644 compiler/wat/log/log1.wat create mode 100644 compiler/wat/log/log2.wat create mode 100644 compiler/wat/log/log3.wat create mode 100644 compiler/wat/log/log4.wat delete mode 100644 zink/src/ffi/memory.rs diff --git a/codegen/src/asm.rs b/codegen/src/asm.rs index bde656f2b..67f039823 100644 --- a/codegen/src/asm.rs +++ b/codegen/src/asm.rs @@ -44,8 +44,8 @@ impl Assembler { pub fn increment_sp(&mut self, items: u8) -> Result<()> { self.sp += items; - // TODO: fix this limitation: should be 1024. - if self.sp > 12 { + // TODO: fix this limitation: should be 1024. (#127) + if self.sp > 254 { return Err(Error::StackOverflow(self.sp)); } diff --git a/codegen/src/data.rs b/codegen/src/data.rs new file mode 100644 index 000000000..d5fe50731 --- /dev/null +++ b/codegen/src/data.rs @@ -0,0 +1,43 @@ +//! Dataset in code generation + +use crate::{Error, Result}; +use std::{ + collections::BTreeMap, + ops::{Deref, DerefMut}, +}; + +/// Data section conversion +/// +/// NOTE: current only support constant expression. +#[derive(Default, Clone, Debug)] +pub struct DataSet(BTreeMap>); + +impl DataSet { + /// Load data from offset and size + pub fn load(&self, offset: i32, size: usize) -> Result> { + for ptr in self.0.keys().cloned().rev() { + if offset >= ptr { + let start = (offset - ptr) as usize; + let data = self.get(&ptr).ok_or(Error::DataNotFound(offset, size))?; + + return Ok(data[start..start + size].to_vec()); + } + } + + Err(Error::DataNotFound(offset, size)) + } +} + +impl Deref for DataSet { + type Target = BTreeMap>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for DataSet { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/codegen/src/func.rs b/codegen/src/func.rs index 6663a613f..09b72c4d1 100644 --- a/codegen/src/func.rs +++ b/codegen/src/func.rs @@ -45,6 +45,14 @@ pub enum Func { Sstore, /// Run function log0. Log0, + /// Run function log1. + Log1, + /// Run function log2. + Log2, + /// Run function log3. + Log3, + /// Run function log4. + Log4, } impl Func { @@ -55,6 +63,10 @@ impl Func { Self::Sload => 1, Self::Sstore => 2, Self::Log0 => 2, + Self::Log1 => 4, + Self::Log2 => 6, + Self::Log3 => 8, + Self::Log4 => 10, } } @@ -65,6 +77,10 @@ impl Func { Self::Sload => 1, Self::Sstore => 0, Self::Log0 => 0, + Self::Log1 => 0, + Self::Log2 => 0, + Self::Log3 => 0, + Self::Log4 => 0, } } @@ -101,12 +117,7 @@ impl Func { /// are necessary to just stay in the code /// section #109 pub fn is_embedded(&self) -> bool { - match self { - Self::Select => true, - Self::Sload => true, - Self::Sstore => true, - Self::Log0 => true, - } + true } } @@ -115,11 +126,21 @@ impl TryFrom<(&str, &str)> for Func { fn try_from(import: (&str, &str)) -> Result { let (module, name) = import; + // NOTE: `select` is not external call + // so we don't need to check process it + // here match import { ("evm", "sload") => Ok(Self::Sload), ("evm", "sstore") => Ok(Self::Sstore), ("evm", "log0") => Ok(Self::Log0), - _ => Err(Error::HostFuncNotFound(module.into(), name.into())), + ("evm", "log1") => Ok(Self::Log1), + ("evm", "log2") => Ok(Self::Log2), + ("evm", "log3") => Ok(Self::Log3), + ("evm", "log4") => Ok(Self::Log4), + _ => { + tracing::error!("Failed to load host function: {:?}", import); + Err(Error::HostFuncNotFound(module.into(), name.into())) + } } } } diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 3dc6c1e3e..bcdfd516d 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -2,20 +2,18 @@ #![deny(missing_docs)] #![recursion_limit = "1024"] -use std::collections::BTreeMap; - pub use crate::{ abi::{ToLSBytes, Type}, asm::Assembler, codegen::CodeGen, control::{ControlStack, ControlStackFrame, ControlStackFrameType}, + data::DataSet, func::Func, jump::{Code, JumpTable}, local::{LocalSlot, Locals}, masm::MacroAssembler, result::{Error, Result}, }; -// use indexmap::IndexMap; use smallvec::SmallVec; pub mod abi; @@ -23,6 +21,7 @@ mod asm; mod backtrace; mod codegen; mod control; +mod data; mod func; mod jump; mod local; @@ -40,8 +39,3 @@ pub type Buffer = SmallVec<[u8; BUFFER_LIMIT]>; /// Imported functions. /// pub type Imports = IndexMap; pub type Imports = Vec; - -/// Data section conversion -/// -/// NOTE: current only support constant expression. -pub type DataSet = BTreeMap>; diff --git a/codegen/src/result.rs b/codegen/src/result.rs index 94bf7bcda..b273bcd3a 100644 --- a/codegen/src/result.rs +++ b/codegen/src/result.rs @@ -12,6 +12,9 @@ pub enum Error { /// Failed to pop control stack frame. #[error("Control stack underflow")] ControlStackUnderflow, + /// Data not found in data section. + #[error("Data not found in data setction, offset {0}, size {1}")] + DataNotFound(i32, usize), /// Failed to register program counter to function index. #[error("Function {0} already exists in jump table")] DuplicateFunc(u32), @@ -67,7 +70,7 @@ pub enum Error { #[error("Stack index is out of range {0}, max is 32 (0x400)")] StackIndexOutOfRange(u8), /// Failed to increment stack pointer. - #[error("Stack overflow, max is 12 stack items, got {0}")] + #[error("Stack overflow, max is 1024 stack items, got {0}")] StackOverflow(u8), /// Failed to decrement stack pointer. #[error("Stack underflow, current stack items {0}, expect at least {1}")] diff --git a/codegen/src/visitor/call.rs b/codegen/src/visitor/call.rs index fbcd1cad6..104fffc40 100644 --- a/codegen/src/visitor/call.rs +++ b/codegen/src/visitor/call.rs @@ -71,8 +71,15 @@ impl CodeGen { match func { Func::Sstore => self.masm._sstore(), Func::Sload => self.masm._sload(), - Func::Log0 => self.log0(), - _ => Err(Error::UnsupportedHostFunc(func)), + Func::Log0 => self.log(0), + Func::Log1 => self.log(1), + Func::Log2 => self.log(2), + Func::Log3 => self.log(3), + Func::Log4 => self.log(4), + _ => { + tracing::error!("unsupported embedded function {func:?}"); + Err(Error::UnsupportedHostFunc(func)) + } } } diff --git a/codegen/src/visitor/log.rs b/codegen/src/visitor/log.rs index 09047458f..ae4b77892 100644 --- a/codegen/src/visitor/log.rs +++ b/codegen/src/visitor/log.rs @@ -27,7 +27,7 @@ impl CodeGen { bytes[..offset_len].copy_from_slice(&data[1..(1 + offset_len)]); i32::from_le_bytes(bytes) }; - tracing::debug!("log0 offset: {:?}", offset); + tracing::debug!("log offset: {:?}", offset); // Parse size. if !(0x5e..0x8f).contains(&data[offset_len + 1]) { @@ -39,34 +39,52 @@ impl CodeGen { bytes[..size_bytes.len()].copy_from_slice(size_bytes); i32::from_le_bytes(bytes) }; - tracing::debug!("log0 size: {:?}", size); + tracing::debug!("log size: {:?}", size); Ok((offset, size)) } - /// Logs a message without topics. - pub fn log0(&mut self) -> Result<()> { - let (offset, size) = self.log_data()?; - let size = size as usize; - let data = self - .dataset - .get(&offset) - .ok_or(Error::InvalidDataOffset(offset))?; - - tracing::debug!("log0 data: {:?}", data); - if data.len() != size { - return Err(Error::InvalidDataSize(size)); + /// Log a message with topics. + pub fn log(&mut self, count: usize) -> Result<()> { + let mut topics = Vec::>::default(); + for topic in (1..=count).rev() { + let (offset, size) = self.log_data()?; + let size = size as usize; + let data = self.dataset.load(offset, size)?; + + tracing::debug!("log{count} topic{topic}: {:?}", data); + topics.push(data); + } + + let name = { + let (offset, size) = self.log_data()?; + let size = size as usize; + let data = self.dataset.load(offset, size)?; + + tracing::debug!("log1 name: {:?}", data); + data + }; + + for topic in topics { + self.masm.push(&topic)?; } // 1. write data to memory - let MemoryInfo { offset, size } = self.masm.memory_write_bytes(data)?; + let MemoryInfo { offset, size } = self.masm.memory_write_bytes(&name)?; - // 2. prepare the offset and size of the data. + // 3. prepare the offset and size of the data. self.masm.push(&size.to_ls_bytes())?; self.masm.push(&offset)?; - // 3. run log0 for the data - self.masm._log0()?; + // 4. run log for the data + match count { + 0 => self.masm._log0(), + 1 => self.masm._log1(), + 2 => self.masm._log2(), + 3 => self.masm._log3(), + 4 => self.masm._log4(), + _ => unreachable!("invalid topics"), + }?; Ok(()) } diff --git a/compiler/tests/log.rs b/compiler/tests/log.rs index 73578fbed..68cc74afa 100644 --- a/compiler/tests/log.rs +++ b/compiler/tests/log.rs @@ -14,3 +14,83 @@ fn log0() -> Result<()> { assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32()); Ok(()) } + +#[test] +fn log1() -> Result<()> { + let bytecode = common::load("log", "log1")?; + + // returns the bigger number. + let info = EVM::run(&bytecode, &[]); + assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32()); + assert_eq!( + info.logs[0].topics[0].to_vec(), + b"pong".to_vec().to_bytes32() + ); + Ok(()) +} + +#[test] +fn log2() -> Result<()> { + let bytecode = common::load("log", "log2")?; + + // returns the bigger number. + let info = EVM::run(&bytecode, &[]); + assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32()); + assert_eq!( + info.logs[0].topics[0].to_vec(), + b"pong".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[1].to_vec(), + b"ping".to_vec().to_bytes32() + ); + Ok(()) +} + +#[test] +fn log3() -> Result<()> { + let bytecode = common::load("log", "log3")?; + + // returns the bigger number. + let info = EVM::run(&bytecode, &[]); + assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32()); + assert_eq!( + info.logs[0].topics[0].to_vec(), + b"pong".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[1].to_vec(), + b"ping".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[2].to_vec(), + b"pong".to_vec().to_bytes32() + ); + Ok(()) +} + +#[test] +fn log4() -> Result<()> { + let bytecode = common::load("log", "log4")?; + + // returns the bigger number. + let info = EVM::run(&bytecode, &[]); + assert_eq!(info.logs[0].data.to_vec(), b"Ping".to_vec().to_bytes32()); + assert_eq!( + info.logs[0].topics[0].to_vec(), + b"pong".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[1].to_vec(), + b"ping".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[2].to_vec(), + b"pong".to_vec().to_bytes32() + ); + assert_eq!( + info.logs[0].topics[3].to_vec(), + b"pong".to_vec().to_bytes32() + ); + Ok(()) +} diff --git a/compiler/wat/log/log0.wat b/compiler/wat/log/log0.wat index 61e9e216e..4a80ac088 100644 --- a/compiler/wat/log/log0.wat +++ b/compiler/wat/log/log0.wat @@ -1,15 +1,15 @@ (module - (type (;0;) (func (param i32 i32))) - (type (;1;) (func)) - (import "evm" "log0" (func (;0;) (type 0))) + (type (;0;) (func)) + (type (;1;) (func (param i32 i32))) + (import "evm" "log0" (func (;0;) (type 1))) (import "env" "memory" (memory (;0;) 17)) - (func (;1;) (type 1) + (func (;2;) (type 0) i32.const 1048576 i32.const 4 call 0) - (global (;0;) i32 (i32.const 1048580)) + (global (;0;) i32 (i32.const 1048584)) (global (;1;) i32 (i32.const 1048592)) - (export "log" (func 1)) + (export "log0" (func 1)) (export "__data_end" (global 0)) (export "__heap_base" (global 1)) (data (;0;) (i32.const 1048576) "Ping")) diff --git a/compiler/wat/log/log1.wat b/compiler/wat/log/log1.wat new file mode 100644 index 000000000..8b6a273b2 --- /dev/null +++ b/compiler/wat/log/log1.wat @@ -0,0 +1,17 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32 i32 i32 i32))) + (import "evm" "log1" (func (;1;) (type 1))) + (import "env" "memory" (memory (;0;) 17)) + (func (;1;) (type 0) + i32.const 1048576 + i32.const 4 + i32.const 1048580 + i32.const 4 + call 0) + (global (;0;) i32 (i32.const 1048584)) + (global (;1;) i32 (i32.const 1048592)) + (export "log1" (func 1)) + (export "__data_end" (global 0)) + (export "__heap_base" (global 1)) + (data (;0;) (i32.const 1048576) "Pingpong")) diff --git a/compiler/wat/log/log2.wat b/compiler/wat/log/log2.wat new file mode 100644 index 000000000..245941417 --- /dev/null +++ b/compiler/wat/log/log2.wat @@ -0,0 +1,19 @@ +(module + (type (;0;) (func)) + (type (;3;) (func (param i32 i32 i32 i32 i32 i32))) + (import "evm" "log2" (func (;0;) (type 1))) + (import "env" "memory" (memory (;0;) 17)) + (func (;1;) (type 0) + i32.const 1048576 + i32.const 4 + i32.const 1048580 + i32.const 4 + i32.const 1048584 + i32.const 4 + call 0) + (global (;0;) i32 (i32.const 1048588)) + (global (;1;) i32 (i32.const 1048592)) + (export "log2" (func 1)) + (export "__data_end" (global 0)) + (export "__heap_base" (global 1)) + (data (;0;) (i32.const 1048576) "Pingpongping")) diff --git a/compiler/wat/log/log3.wat b/compiler/wat/log/log3.wat new file mode 100644 index 000000000..20429bcc4 --- /dev/null +++ b/compiler/wat/log/log3.wat @@ -0,0 +1,21 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32 i32 i32 i32 i32 i32 i32 i32))) + (import "evm" "log3" (func (;3;) (type 1))) + (import "env" "memory" (memory (;0;) 17)) + (func (;8;) (type 0) + i32.const 1048576 + i32.const 4 + i32.const 1048580 + i32.const 4 + i32.const 1048584 + i32.const 4 + i32.const 1048580 + i32.const 4 + call 0) + (global (;0;) i32 (i32.const 1048588)) + (global (;1;) i32 (i32.const 1048592)) + (export "log3" (func 1)) + (export "__data_end" (global 0)) + (export "__heap_base" (global 1)) + (data (;0;) (i32.const 1048576) "Pingpongping")) diff --git a/compiler/wat/log/log4.wat b/compiler/wat/log/log4.wat new file mode 100644 index 000000000..f0dd4b62f --- /dev/null +++ b/compiler/wat/log/log4.wat @@ -0,0 +1,23 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) + (import "evm" "log4" (func (;3;) (type 1))) + (import "env" "memory" (memory (;0;) 17)) + (func (;8;) (type 0) + i32.const 1048576 + i32.const 4 + i32.const 1048580 + i32.const 4 + i32.const 1048584 + i32.const 4 + i32.const 1048580 + i32.const 4 + i32.const 1048580 + i32.const 4 + call 0) + (global (;0;) i32 (i32.const 1048588)) + (global (;1;) i32 (i32.const 1048592)) + (export "log3" (func 1)) + (export "__data_end" (global 0)) + (export "__heap_base" (global 1)) + (data (;0;) (i32.const 1048576) "Pingpongping")) diff --git a/examples/log/src/lib.rs b/examples/log/src/lib.rs index 7f320a2fe..018b0dc38 100644 --- a/examples/log/src/lib.rs +++ b/examples/log/src/lib.rs @@ -15,16 +15,29 @@ struct Ping; /// TODO: generate this with proc-macro. impl Event for Ping { const NAME: &'static [u8] = b"Ping"; +} + +#[no_mangle] +pub extern "C" fn log0() { + Ping.log0(); +} - fn emit(&self) { - unsafe { - zink::ffi::evm::log0(Self::NAME.as_ptr() as i32, 4); - } - } +#[no_mangle] +pub extern "C" fn log1() { + Ping.log1(b"pong"); +} + +#[no_mangle] +pub extern "C" fn log2() { + Ping.log2(b"pong", b"ping"); +} + +#[no_mangle] +pub extern "C" fn log3() { + Ping.log3(b"pong", b"ping", b"pong"); } -/// Adds two numbers together. #[no_mangle] -pub extern "C" fn log() { - Ping.emit(); +pub extern "C" fn log4() { + Ping.log4(b"pong", b"ping", b"pong", b"pong"); } diff --git a/examples/storage/src/lib.rs b/examples/storage/src/lib.rs index 1e9fedf15..b94b60e4d 100644 --- a/examples/storage/src/lib.rs +++ b/examples/storage/src/lib.rs @@ -13,30 +13,30 @@ use zink::ffi::evm::{sload, sstore}; struct Counter; impl Counter { - fn get() -> i64 { + fn get() -> i32 { unsafe { sload(0) } } - fn set(value: i64) { + fn set(value: i32) { unsafe { sstore(0, value) } } } /// Set value to the storage and get it. #[no_mangle] -pub unsafe extern "C" fn set_and_get(value: i64) -> i64 { +pub unsafe extern "C" fn set_and_get(value: i32) -> i32 { Counter::set(value); Counter::get() } /// Set value to the storage. #[no_mangle] -pub unsafe extern "C" fn set(value: i64) { +pub unsafe extern "C" fn set(value: i32) { Counter::set(value); } /// Get value from the storage. #[no_mangle] -pub unsafe extern "C" fn get() -> i64 { +pub unsafe extern "C" fn get() -> i32 { Counter::get() } diff --git a/zink/src/event.rs b/zink/src/event.rs index be79bacec..f1bb371f1 100644 --- a/zink/src/event.rs +++ b/zink/src/event.rs @@ -1,39 +1,46 @@ //! Event implementation +use crate::ffi; + /// Zink event interface +/// +/// TODO: safety check for the length of the event name pub trait Event { const NAME: &'static [u8]; - /// Returns the first topic. - fn topic_0(&self) -> Option<[u8; 32]> { - None + fn log0(&self) { + unsafe { + ffi::evm::log0(Self::NAME); + } } - /// Returns the second topic. - fn topic_1(&self) -> Option<[u8; 32]> { - None + fn log1(&self, topic: &'static [u8]) { + unsafe { + ffi::evm::log1(Self::NAME, topic); + } } - /// Returns the third topic. - fn topic_2(&self) -> Option<[u8; 32]> { - None + fn log2(&self, topic1: &'static [u8], topic2: &'static [u8]) { + unsafe { + ffi::evm::log2(Self::NAME, topic1, topic2); + } } - /// Returns the fourth topic. - fn topic_3(&self) -> Option<[u8; 32]> { - None + fn log3(&self, topic1: &'static [u8], topic2: &'static [u8], topic3: &'static [u8]) { + unsafe { + ffi::evm::log3(Self::NAME, topic1, topic2, topic3); + } } - /// Returns the event topics. - fn topics(&self) -> [Option<[u8; 32]>; 4] { - [ - self.topic_0(), - self.topic_1(), - self.topic_2(), - self.topic_3(), - ] + fn log4( + &self, + topic1: &'static [u8], + topic2: &'static [u8], + topic3: &'static [u8], + topic4: &'static [u8], + ) { + unsafe { + ffi::evm::log4(Self::NAME, topic1, topic2, topic3, topic4); + } } - - /// Emit the event. - fn emit(&self); } diff --git a/zink/src/ffi/evm.rs b/zink/src/ffi/evm.rs index ab5b14683..fadd7582e 100644 --- a/zink/src/ffi/evm.rs +++ b/zink/src/ffi/evm.rs @@ -4,6 +4,7 @@ // // TODO: Align to 256-bit #20. #[link(wasm_import_module = "evm")] +#[allow(improper_ctypes)] extern "C" { // i32 -> 8 bytes @@ -14,27 +15,31 @@ extern "C" { pub fn sload(key: i32) -> i32; /// Append log record with no topics - /// - /// NOTE: - /// - /// the first argument of this function is the position - /// of the data in the data section. - pub fn log0(offset: i32, size: i32); + pub fn log0(name: &'static [u8]); /// Append log record with one topics - pub fn log1(offset: i32, size: i32); + pub fn log1(name: &'static [u8], topic1: &'static [u8]); /// Append log record with two topics - pub fn log2(offset: i32, size: i32); + pub fn log2(name: &'static [u8], topic1: &'static [u8], topic2: &'static [u8]); /// Append log record with three topics - pub fn log3(offset: i32, size: i32); + pub fn log3( + name: &'static [u8], + topic1: &'static [u8], + topic2: &'static [u8], + topic3: &'static [u8], + ); /// Append log record with four topics - pub fn log4(offset: i32, size: i32); + pub fn log4( + name: &'static [u8], + topic1: &'static [u8], + topic2: &'static [u8], + topic3: &'static [u8], + topic4: &'static [u8], + ); /// Copy code running in current environment to memory pub fn codecopy(destOffset: u32, codeOffset: u32, size: u32); - - // TODO: introduce inline assembly (#115) } diff --git a/zink/src/ffi/memory.rs b/zink/src/ffi/memory.rs deleted file mode 100644 index 185f50716..000000000 --- a/zink/src/ffi/memory.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Memory operations - -#[link(wasm_import_module = "memory")] -extern "C" { - /// Read memory at the given offset with size. - pub fn read_at(offset: u32, size: u32); - - /// Write memory at the given offset with size. - pub fn write_at(offset: u32, size: u32); -} diff --git a/zink/src/ffi/mod.rs b/zink/src/ffi/mod.rs index 83b4325fe..47a0afcd2 100644 --- a/zink/src/ffi/mod.rs +++ b/zink/src/ffi/mod.rs @@ -5,4 +5,3 @@ //! called by the compiler. pub mod evm; -pub mod memory;