wasm-runtime

A wasm runtime
git clone https://git.parazyd.org/wasm-runtime
Log | Files | Refs | README | LICENSE

entrypoint.rs (1768B)


      1 use std::{mem::size_of, slice::from_raw_parts};
      2 
      3 /// Success exit code for contract
      4 pub const SUCCESS: u64 = 0;
      5 
      6 /// This macro is used to flag the contract entrypoint function.
      7 /// All contracts must provide such a function and accept a payload.
      8 ///
      9 /// The payload is a slice of u8 prepended with a little-endian u64
     10 /// that tells the slice's length.
     11 #[macro_export]
     12 macro_rules! entrypoint {
     13     ($process_instruction:ident) => {
     14         /// # Safety
     15         #[no_mangle]
     16         pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 {
     17             let instruction_data = $crate::entrypoint::deserialize(input);
     18 
     19             match $process_instruction(&instruction_data) {
     20                 Ok(()) => $crate::entrypoint::SUCCESS,
     21                 Err(e) => e.into(),
     22             }
     23         }
     24     };
     25 }
     26 
     27 /// Deserialize a given payload in `entrypoint`
     28 /// # Safety
     29 pub unsafe fn deserialize<'a>(input: *mut u8) -> &'a [u8] {
     30     let mut offset: usize = 0;
     31 
     32     let instruction_data_len = *(input.add(offset) as *const u64) as usize;
     33     offset += size_of::<u64>();
     34 
     35     let instruction_data = { from_raw_parts(input.add(offset), instruction_data_len) };
     36 
     37     instruction_data
     38 }
     39 
     40 /// Allocate a piece of memory in the wasm VM
     41 #[no_mangle]
     42 #[cfg(target_arch = "wasm32")]
     43 extern "C" fn __drkruntime_mem_alloc(size: usize) -> *mut u8 {
     44     let align = std::mem::align_of::<usize>();
     45 
     46     if let Ok(layout) = std::alloc::Layout::from_size_align(size, align) {
     47         unsafe {
     48             if layout.size() > 0 {
     49                 let ptr = std::alloc::alloc(layout);
     50                 if !ptr.is_null() {
     51                     return ptr
     52                 }
     53             } else {
     54                 return align as *mut u8
     55             }
     56         }
     57     }
     58 
     59     std::process::abort();
     60 }