1#![no_std]
2#![doc = include_str!("../README.md")]
3
4pub use polkavm_derive_impl_macro::__PRIVATE_DO_NOT_USE_polkavm_define_abi as polkavm_define_abi;
5pub use polkavm_derive_impl_macro::__PRIVATE_DO_NOT_USE_polkavm_export as polkavm_export;
6pub use polkavm_derive_impl_macro::__PRIVATE_DO_NOT_USE_polkavm_import as polkavm_import;
7
8pub mod default_abi {
9 polkavm_derive_impl_macro::__PRIVATE_DO_NOT_USE_polkavm_impl_abi_support!();
10}
11
12#[cfg(any(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"), doc))]
19#[inline]
20pub fn sbrk(size: usize) -> *mut u8 {
21 unsafe {
23 let address;
24 core::arch::asm!(
25 ".insn r 0xb, 1, 0, {dst}, {size}, zero",
26 size = in(reg) size,
27 dst = lateout(reg) address,
28 );
29 address
30 }
31}
32
33#[inline]
35#[allow(unused_assignments)]
36#[allow(unused_mut)]
37#[allow(clippy::missing_safety_doc)]
38#[allow(clippy::undocumented_unsafe_blocks)]
39pub unsafe fn memset(mut dst: *mut u8, value: usize, mut count: usize) {
40 #[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"))]
41 unsafe {
42 core::arch::asm!(
43 ".insn r 0xb, 2, 0, zero, zero, zero",
44 inout("a0") dst,
45 in("a1") value,
46 inout("a2") count,
47 );
48 }
49
50 #[cfg(not(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e")))]
51 unsafe {
52 core::ptr::write_bytes(dst, value as u8, count);
53 }
54}
55
56#[inline]
57pub fn heap_base() -> *mut core::ffi::c_void {
58 #[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"))]
59 unsafe {
60 let mut output;
61 core::arch::asm!(
62 ".insn r 0xb, 3, 0, {dst}, zero, zero",
63 dst = out(reg) output,
64 );
65 output
66 }
67
68 #[cfg(not(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e")))]
69 {
70 core::ptr::null_mut()
71 }
72}
73
74pub struct LeakingAllocator;
76
77#[cfg(any(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"), doc))]
78unsafe impl core::alloc::GlobalAlloc for LeakingAllocator {
79 #[inline]
80 unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
81 let pointer = crate::sbrk(0);
82 let padding = (-(pointer as isize)) as usize & (layout.align() - 1);
83 let size = layout.size().wrapping_add(padding);
84 if crate::sbrk(size).is_null() {
85 return core::ptr::null_mut();
86 }
87
88 pointer.add(padding)
89 }
90
91 #[inline]
92 unsafe fn dealloc(&self, _ptr: *mut u8, _layout: core::alloc::Layout) {}
93}
94
95#[cfg(any(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"), doc))]
97#[macro_export]
98macro_rules! min_stack_size {
99 ($size:expr) => {
100 ::core::arch::global_asm!(
101 ".pushsection .polkavm_min_stack_size,\"R\",@note\n",
102 ".4byte {size}",
103 ".popsection\n",
104 size = const $size,
105 );
106 }
107}
108
109#[cfg(target_pointer_width = "32")]
110#[cfg(any(all(target_arch = "riscv32", target_feature = "e"), doc))]
111#[no_mangle]
112pub unsafe extern "C" fn __atomic_fetch_add_8(address: *mut u64, value: u64) -> u64 {
113 unsafe {
114 let old_value = *address;
115 *address += value;
116 old_value
117 }
118}