bobcat_entry/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6#[cfg(feature = "alloc")]
7use alloc::vec::Vec;
8
9pub use bobcat_maths::U;
10
11pub type Address = [u8; 20];
12
13#[cfg(target_arch = "wasm32")]
14mod impls {
15    #[link(wasm_import_module = "vm_hooks")]
16    unsafe extern "C" {
17        #[allow(unused)]
18        pub(crate) fn pay_for_memory_grow(pages: u16);
19        pub(crate) fn write_result(d: *const u8, l: usize);
20        pub(crate) fn read_args(out: *mut u8);
21        pub(crate) fn msg_sender(addr: *mut u8);
22        pub(crate) fn contract_address(addr: *mut u8);
23        pub(crate) fn msg_value(value: *mut u8);
24        pub(crate) fn msg_reentrant() -> bool;
25        pub fn chain_id() -> u64;
26        pub(crate) fn account_code_size(address: *const u8) -> usize;
27    }
28}
29
30#[cfg(all(not(target_arch = "wasm32"), feature = "std"))]
31mod impls {
32    use core::{ptr::copy_nonoverlapping, slice::from_raw_parts};
33
34    #[allow(unused)]
35    pub(crate) unsafe fn pay_for_memory_grow(_: u16) {}
36
37    pub(crate) unsafe fn write_result(d: *const u8, l: usize) {
38        println!("{}", const_hex::encode(unsafe { from_raw_parts(d, l) }));
39    }
40
41    pub(crate) unsafe fn read_args(_out: *mut u8) {
42        unimplemented!("read from stdin separately. todo");
43    }
44
45    pub(crate) unsafe fn msg_sender(out: *mut u8) {
46        unsafe { copy_nonoverlapping([0u8; 32].as_ptr(), out, 32) }
47    }
48
49    pub(crate) unsafe fn contract_address(out: *mut u8) {
50        unsafe { copy_nonoverlapping([0u8; 32].as_ptr(), out, 32) }
51    }
52
53    pub(crate) unsafe fn msg_value(out: *mut u8) {
54        unsafe { copy_nonoverlapping([0u8; 32].as_ptr(), out, 32) }
55    }
56
57    pub(crate) unsafe fn msg_reentrant() -> bool {
58        false
59    }
60
61    pub(crate) unsafe fn chain_id() -> u64 {
62        0
63    }
64
65    pub(crate) unsafe fn account_code_size(_: *const u8) -> usize {
66        0
67    }
68}
69
70#[cfg(all(not(target_arch = "wasm32"), not(feature = "std")))]
71mod impls {
72    pub(crate) unsafe fn pay_for_memory_grow(_: u16) {}
73
74    pub(crate) unsafe fn write_result(_: *const u8, _: usize) {}
75
76    pub(crate) unsafe fn read_args(_out: *mut u8) {}
77
78    pub(crate) unsafe fn msg_sender(_: *mut u8) {}
79
80    pub(crate) unsafe fn contract_address(_: *mut u8) {}
81
82    pub(crate) unsafe fn msg_value(_: *mut u8) {}
83
84    pub(crate) unsafe fn msg_reentrant() -> bool {
85        false
86    }
87
88    pub(crate) unsafe fn chain_id() -> u64 {
89        0
90    }
91
92    pub(crate) unsafe fn account_code_size(_: *const u8) -> usize {
93        0
94    }
95}
96
97#[unsafe(no_mangle)]
98#[cfg(not(feature = "dont-define-symbols"))]
99pub unsafe fn mark_used() {
100    unsafe { impls::pay_for_memory_grow(0) }
101    panic!();
102}
103
104pub fn write_result(s: &[u8]) {
105    unsafe { impls::write_result(s.as_ptr(), s.len()) }
106}
107
108pub fn read_args<const CAP: usize>(len: usize) -> ([u8; CAP], usize) {
109    assert!(CAP >= len, "cap not enough");
110    let mut b = [0u8; CAP];
111    unsafe { impls::read_args(b.as_mut_ptr()) };
112    (b, len)
113}
114
115#[macro_export]
116macro_rules! read_args_safe {
117    ($len:expr, $max_len:expr) => {{
118        assert!($max_len >= $len);
119        $crate::read_args::<$max_len>($len).0
120    }};
121}
122
123#[cfg(feature = "alloc")]
124pub fn read_args_vec(len: usize) -> Vec<u8> {
125    let mut b = Vec::with_capacity(len);
126    unsafe {
127        impls::read_args(b.as_mut_ptr());
128        b.set_len(len);
129    };
130    b
131}
132
133pub fn msg_sender() -> Address {
134    let mut b = [0u8; 20];
135    unsafe { impls::msg_sender(b.as_mut_ptr()) }
136    b
137}
138
139pub fn contract_address() -> Address {
140    let mut b = [0u8; 20];
141    unsafe { impls::contract_address(b.as_mut_ptr()) }
142    b
143}
144
145pub fn msg_value() -> U {
146    let mut b = [0u8; 32];
147    unsafe { impls::msg_value(b.as_mut_ptr()) }
148    U(b)
149}
150
151pub fn msg_reentrant() -> bool {
152    unsafe { impls::msg_reentrant() }
153}
154
155pub fn code_size(addr: Address) -> usize {
156    unsafe { impls::account_code_size(addr.as_ptr()) }
157}
158
159pub fn chain_id() -> u64 {
160    unsafe { impls::chain_id() }
161}