1use crate::func_data_registry::VMFuncRef;
8use crate::global::Global;
9use crate::instance::Instance;
10use crate::memory::LinearMemory;
11use crate::sig_registry::VMSharedSignatureIndex;
12use crate::table::Table;
13use crate::trap::{Trap, TrapCode};
14use crate::VMExternRef;
15use std::any::Any;
16use std::convert::TryFrom;
17use std::fmt;
18use std::ptr::{self, NonNull};
19use std::sync::Arc;
20use std::u32;
21
22#[derive(Copy, Clone, Eq)]
27pub union VMFunctionEnvironment {
28 pub vmctx: *mut VMContext,
30 pub host_env: *mut std::ffi::c_void,
32}
33
34impl VMFunctionEnvironment {
35 pub fn is_null(&self) -> bool {
37 unsafe { self.host_env.is_null() }
38 }
39}
40
41impl std::fmt::Debug for VMFunctionEnvironment {
42 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43 f.debug_struct("VMFunctionEnvironment")
44 .field("vmctx_or_hostenv", unsafe { &self.host_env })
45 .finish()
46 }
47}
48
49impl std::cmp::PartialEq for VMFunctionEnvironment {
50 fn eq(&self, rhs: &Self) -> bool {
51 unsafe { self.host_env as usize == rhs.host_env as usize }
52 }
53}
54
55impl std::hash::Hash for VMFunctionEnvironment {
56 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
57 unsafe {
58 self.vmctx.hash(state);
59 }
60 }
61}
62
63#[derive(Debug)]
66#[repr(C)]
67pub struct FunctionExtent {
68 pub address: FunctionBodyPtr,
71 pub length: usize,
73}
74
75#[derive(Debug, Copy, Clone)]
77#[repr(C)]
78pub struct VMFunctionImport {
79 pub body: FunctionBodyPtr,
81
82 pub signature: VMSharedSignatureIndex,
84
85 pub trampoline: Option<VMTrampoline>,
87
88 pub environment: VMFunctionEnvironment,
90}
91
92#[cfg(test)]
93mod test_vmfunction_import {
94 use super::VMFunctionImport;
95 use crate::VMOffsets;
96 use memoffset::offset_of;
97 use near_vm_types::ModuleInfo;
98 use std::mem::size_of;
99
100 #[test]
101 fn check_vmfunction_import_offsets() {
102 let module = ModuleInfo::new();
103 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
104 assert_eq!(size_of::<VMFunctionImport>(), usize::from(offsets.size_of_vmfunction_import()));
105 assert_eq!(
106 offset_of!(VMFunctionImport, body),
107 usize::from(offsets.vmfunction_import_body())
108 );
109 assert_eq!(
110 offset_of!(VMFunctionImport, environment),
111 usize::from(offsets.vmfunction_import_vmctx())
112 );
113 }
114}
115
116#[derive(Debug, Copy, Clone)]
118#[repr(C)]
119pub struct VMLocalFunction {
120 pub body: FunctionBodyPtr,
122
123 pub length: u32,
125
126 pub signature: VMSharedSignatureIndex,
128
129 pub trampoline: VMTrampoline,
131}
132
133#[repr(C)]
142pub struct VMDynamicFunctionContext<T: Sized + Send + Sync> {
143 pub address: *const VMFunctionBody,
148
149 pub ctx: T,
151}
152
153unsafe impl<T: Sized + Send + Sync> Send for VMDynamicFunctionContext<T> {}
156unsafe impl<T: Sized + Send + Sync> Sync for VMDynamicFunctionContext<T> {}
159
160impl<T: Sized + Clone + Send + Sync> Clone for VMDynamicFunctionContext<T> {
161 fn clone(&self) -> Self {
162 Self { address: self.address, ctx: self.ctx.clone() }
163 }
164}
165
166#[cfg(test)]
167mod test_vmdynamicfunction_import_context {
168 use super::VMDynamicFunctionContext;
169 use crate::VMOffsets;
170 use memoffset::offset_of;
171 use near_vm_types::ModuleInfo;
172 use std::mem::size_of;
173
174 #[test]
175 fn check_vmdynamicfunction_import_context_offsets() {
176 let module = ModuleInfo::new();
177 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
178 assert_eq!(
179 size_of::<VMDynamicFunctionContext<usize>>(),
180 usize::from(offsets.size_of_vmdynamicfunction_import_context())
181 );
182 assert_eq!(
183 offset_of!(VMDynamicFunctionContext<usize>, address),
184 usize::from(offsets.vmdynamicfunction_import_context_address())
185 );
186 assert_eq!(
187 offset_of!(VMDynamicFunctionContext<usize>, ctx),
188 usize::from(offsets.vmdynamicfunction_import_context_ctx())
189 );
190 }
191}
192
193#[repr(C)]
198pub struct VMFunctionBody(u8);
199
200#[cfg(test)]
201mod test_vmfunction_body {
202 use super::VMFunctionBody;
203 use std::mem::size_of;
204
205 #[test]
206 fn check_vmfunction_body_offsets() {
207 assert_eq!(size_of::<VMFunctionBody>(), 1);
208 }
209}
210
211#[derive(Clone, Copy, Debug)]
213#[repr(transparent)]
214pub struct FunctionBodyPtr(pub *const VMFunctionBody);
215
216impl std::ops::Deref for FunctionBodyPtr {
217 type Target = *const VMFunctionBody;
218
219 fn deref(&self) -> &Self::Target {
220 &self.0
221 }
222}
223
224unsafe impl Send for FunctionBodyPtr {}
227
228unsafe impl Sync for FunctionBodyPtr {}
231
232#[derive(Debug, Copy, Clone, PartialEq)]
234#[repr(C)]
235pub enum VMFunctionKind {
236 Static,
243
244 Dynamic,
250}
251
252#[derive(Debug, Clone)]
255#[repr(C)]
256pub struct VMTableImport {
257 pub definition: NonNull<VMTableDefinition>,
259
260 pub from: Arc<dyn Table>,
262}
263
264#[cfg(test)]
265mod test_vmtable_import {
266 use super::VMTableImport;
267 use crate::VMOffsets;
268 use memoffset::offset_of;
269 use near_vm_types::ModuleInfo;
270 use std::mem::size_of;
271
272 #[test]
273 fn check_vmtable_import_offsets() {
274 let module = ModuleInfo::new();
275 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
276 assert_eq!(size_of::<VMTableImport>(), usize::from(offsets.size_of_vmtable_import()));
277 assert_eq!(
278 offset_of!(VMTableImport, definition),
279 usize::from(offsets.vmtable_import_definition())
280 );
281 assert_eq!(offset_of!(VMTableImport, from), usize::from(offsets.vmtable_import_from()));
282 }
283}
284
285#[derive(Debug, Clone)]
288#[repr(C)]
289pub struct VMMemoryImport {
290 pub definition: NonNull<VMMemoryDefinition>,
292
293 pub from: Arc<LinearMemory>,
295}
296
297#[cfg(test)]
298mod test_vmmemory_import {
299 use super::VMMemoryImport;
300 use crate::VMOffsets;
301 use memoffset::offset_of;
302 use near_vm_types::ModuleInfo;
303 use std::mem::size_of;
304
305 #[test]
306 fn check_vmmemory_import_offsets() {
307 let module = ModuleInfo::new();
308 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
309 assert_eq!(size_of::<VMMemoryImport>(), usize::from(offsets.size_of_vmmemory_import()));
310 assert_eq!(
311 offset_of!(VMMemoryImport, definition),
312 usize::from(offsets.vmmemory_import_definition())
313 );
314 assert_eq!(offset_of!(VMMemoryImport, from), usize::from(offsets.vmmemory_import_from()));
315 }
316}
317
318#[derive(Debug, Clone)]
321#[repr(C)]
322pub struct VMGlobalImport {
323 pub definition: NonNull<VMGlobalDefinition>,
325
326 pub from: Arc<Global>,
328}
329
330unsafe impl Send for VMGlobalImport {}
335unsafe impl Sync for VMGlobalImport {}
341
342#[cfg(test)]
343mod test_vmglobal_import {
344 use super::VMGlobalImport;
345 use crate::VMOffsets;
346 use memoffset::offset_of;
347 use near_vm_types::ModuleInfo;
348 use std::mem::size_of;
349
350 #[test]
351 fn check_vmglobal_import_offsets() {
352 let module = ModuleInfo::new();
353 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
354 assert_eq!(size_of::<VMGlobalImport>(), usize::from(offsets.size_of_vmglobal_import()));
355 assert_eq!(
356 offset_of!(VMGlobalImport, definition),
357 usize::from(offsets.vmglobal_import_definition())
358 );
359 assert_eq!(offset_of!(VMGlobalImport, from), usize::from(offsets.vmglobal_import_from()));
360 }
361}
362
363#[derive(Debug, Copy, Clone)]
367#[repr(C)]
368pub struct VMMemoryDefinition {
369 pub base: *mut u8,
371
372 pub current_length: usize,
374}
375
376unsafe impl Send for VMMemoryDefinition {}
380unsafe impl Sync for VMMemoryDefinition {}
386
387impl VMMemoryDefinition {
388 pub(crate) unsafe fn memory_copy(&self, dst: u32, src: u32, len: u32) -> Result<(), Trap> {
400 if src.checked_add(len).map_or(true, |n| usize::try_from(n).unwrap() > self.current_length)
402 || dst
403 .checked_add(len)
404 .map_or(true, |m| usize::try_from(m).unwrap() > self.current_length)
405 {
406 return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
407 }
408
409 let dst = usize::try_from(dst).unwrap();
410 let src = usize::try_from(src).unwrap();
411
412 let dst = self.base.add(dst);
415 let src = self.base.add(src);
416 ptr::copy(src, dst, len as usize);
417
418 Ok(())
419 }
420
421 pub(crate) unsafe fn memory_fill(&self, dst: u32, val: u32, len: u32) -> Result<(), Trap> {
432 if dst.checked_add(len).map_or(true, |m| usize::try_from(m).unwrap() > self.current_length)
433 {
434 return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
435 }
436
437 let dst = isize::try_from(dst).unwrap();
438 let val = val as u8;
439
440 let dst = self.base.offset(dst);
443 ptr::write_bytes(dst, val, len as usize);
444
445 Ok(())
446 }
447}
448
449#[cfg(test)]
450mod test_vmmemory_definition {
451 use super::VMMemoryDefinition;
452 use crate::VMOffsets;
453 use memoffset::offset_of;
454 use near_vm_types::ModuleInfo;
455 use std::mem::size_of;
456
457 #[test]
458 fn check_vmmemory_definition_offsets() {
459 let module = ModuleInfo::new();
460 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
461 assert_eq!(
462 size_of::<VMMemoryDefinition>(),
463 usize::from(offsets.size_of_vmmemory_definition())
464 );
465 assert_eq!(
466 offset_of!(VMMemoryDefinition, base),
467 usize::from(offsets.vmmemory_definition_base())
468 );
469 assert_eq!(
470 offset_of!(VMMemoryDefinition, current_length),
471 usize::from(offsets.vmmemory_definition_current_length())
472 );
473 }
474}
475
476#[derive(Debug, Clone, Copy)]
479#[repr(C)]
480pub struct VMTableDefinition {
481 pub base: *mut u8,
483
484 pub current_elements: u32,
486}
487
488#[cfg(test)]
489mod test_vmtable_definition {
490 use super::VMTableDefinition;
491 use crate::VMOffsets;
492 use memoffset::offset_of;
493 use near_vm_types::ModuleInfo;
494 use std::mem::size_of;
495
496 #[test]
497 fn check_vmtable_definition_offsets() {
498 let module = ModuleInfo::new();
499 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
500 assert_eq!(
501 size_of::<VMTableDefinition>(),
502 usize::from(offsets.size_of_vmtable_definition())
503 );
504 assert_eq!(
505 offset_of!(VMTableDefinition, base),
506 usize::from(offsets.vmtable_definition_base())
507 );
508 assert_eq!(
509 offset_of!(VMTableDefinition, current_elements),
510 usize::from(offsets.vmtable_definition_current_elements())
511 );
512 }
513}
514
515#[derive(Clone, Copy)]
523#[repr(C, align(16))]
524pub union VMGlobalDefinitionStorage {
525 as_i32: i32,
526 as_u32: u32,
527 as_f32: f32,
528 as_i64: i64,
529 as_u64: u64,
530 as_f64: f64,
531 as_u128: u128,
532 as_funcref: VMFuncRef,
533 as_externref: VMExternRef,
534 bytes: [u8; 16],
535}
536
537impl fmt::Debug for VMGlobalDefinitionStorage {
538 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
539 f.debug_struct("VMGlobalDefinitionStorage").field("bytes", unsafe { &self.bytes }).finish()
540 }
541}
542
543#[derive(Debug, Clone)]
548#[repr(C, align(16))]
549pub struct VMGlobalDefinition {
550 storage: VMGlobalDefinitionStorage,
551 }
553
554#[cfg(test)]
555mod test_vmglobal_definition {
556 use super::VMGlobalDefinition;
557 use crate::{VMFuncRef, VMOffsets};
558 use more_asserts::assert_ge;
559 use near_vm_types::ModuleInfo;
560 use std::mem::{align_of, size_of};
561
562 #[test]
563 fn check_vmglobal_definition_alignment() {
564 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<i32>());
565 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<i64>());
566 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<f32>());
567 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<f64>());
568 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<VMFuncRef>());
569 assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<[u8; 16]>());
570 }
571
572 #[test]
573 fn check_vmglobal_definition_offsets() {
574 let module = ModuleInfo::new();
575 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
576 assert_eq!(
577 size_of::<*const VMGlobalDefinition>(),
578 usize::from(offsets.size_of_vmglobal_local())
579 );
580 }
581
582 #[test]
583 fn check_vmglobal_begins_aligned() {
584 let module = ModuleInfo::new();
585 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
586 assert_eq!(offsets.vmctx_globals_begin() % 16, 0);
587 }
588}
589
590impl VMGlobalDefinition {
591 pub fn new() -> Self {
593 Self { storage: VMGlobalDefinitionStorage { bytes: [0; 16] } }
594 }
595
596 pub fn to_i32(&self) -> i32 {
600 unsafe { self.storage.as_i32 }
601 }
602
603 pub unsafe fn as_i32_mut(&mut self) -> &mut i32 {
612 &mut self.storage.as_i32
613 }
614
615 pub fn to_u32(&self) -> u32 {
619 unsafe { self.storage.as_u32 }
620 }
621
622 pub unsafe fn as_u32_mut(&mut self) -> &mut u32 {
631 &mut self.storage.as_u32
632 }
633
634 pub fn to_i64(&self) -> i64 {
638 unsafe { self.storage.as_i64 }
639 }
640
641 pub unsafe fn as_i64_mut(&mut self) -> &mut i64 {
650 &mut self.storage.as_i64
651 }
652
653 pub fn to_u64(&self) -> u64 {
657 unsafe { self.storage.as_u64 }
658 }
659
660 pub unsafe fn as_u64_mut(&mut self) -> &mut u64 {
669 &mut self.storage.as_u64
670 }
671
672 pub fn to_f32(&self) -> f32 {
676 unsafe { self.storage.as_f32 }
677 }
678
679 pub unsafe fn as_f32_mut(&mut self) -> &mut f32 {
688 &mut self.storage.as_f32
689 }
690
691 pub fn to_f64(&self) -> f64 {
695 unsafe { self.storage.as_f64 }
696 }
697
698 pub unsafe fn as_f64_mut(&mut self) -> &mut f64 {
707 &mut self.storage.as_f64
708 }
709
710 pub fn to_funcref(&self) -> VMFuncRef {
714 unsafe { self.storage.as_funcref }
715 }
716
717 pub unsafe fn as_funcref_mut(&mut self) -> &mut VMFuncRef {
726 &mut self.storage.as_funcref
727 }
728
729 pub unsafe fn as_externref_mut(&mut self) -> &mut VMExternRef {
738 &mut self.storage.as_externref
739 }
740
741 pub fn to_externref(&self) -> VMExternRef {
745 unsafe { self.storage.as_externref }
746 }
747
748 pub fn to_u128(&self) -> u128 {
752 unsafe { self.storage.as_u128 }
753 }
754
755 pub unsafe fn as_u128_mut(&mut self) -> &mut u128 {
764 &mut self.storage.as_u128
765 }
766
767 pub fn to_bytes(&self) -> [u8; 16] {
769 unsafe { self.storage.bytes }
770 }
771
772 pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8; 16] {
780 &mut self.storage.bytes
781 }
782}
783
784#[cfg(test)]
785mod test_vmshared_signature_index {
786 use super::VMSharedSignatureIndex;
787 use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};
788 use near_vm_types::ModuleInfo;
789 use std::mem::size_of;
790
791 #[test]
792 fn check_vmshared_signature_index() {
793 let module = ModuleInfo::new();
794 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
795 assert_eq!(
796 size_of::<VMSharedSignatureIndex>(),
797 usize::from(offsets.size_of_vmshared_signature_index())
798 );
799 }
800
801 #[test]
802 fn check_target_shared_signature_index() {
803 assert_eq!(size_of::<VMSharedSignatureIndex>(), size_of::<TargetSharedSignatureIndex>());
804 }
805}
806
807#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
811#[repr(C)]
812pub struct VMCallerCheckedAnyfunc {
813 pub func_ptr: *const VMFunctionBody,
815 pub type_index: VMSharedSignatureIndex,
817 pub vmctx: VMFunctionEnvironment,
819 }
821
822#[cfg(test)]
823mod test_vmcaller_checked_anyfunc {
824 use super::VMCallerCheckedAnyfunc;
825 use crate::VMOffsets;
826 use memoffset::offset_of;
827 use near_vm_types::ModuleInfo;
828 use std::mem::size_of;
829
830 #[test]
831 fn check_vmcaller_checked_anyfunc_offsets() {
832 let module = ModuleInfo::new();
833 let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
834 assert_eq!(
835 size_of::<VMCallerCheckedAnyfunc>(),
836 usize::from(offsets.size_of_vmcaller_checked_anyfunc())
837 );
838 assert_eq!(
839 offset_of!(VMCallerCheckedAnyfunc, func_ptr),
840 usize::from(offsets.vmcaller_checked_anyfunc_func_ptr())
841 );
842 assert_eq!(
843 offset_of!(VMCallerCheckedAnyfunc, type_index),
844 usize::from(offsets.vmcaller_checked_anyfunc_type_index())
845 );
846 assert_eq!(
847 offset_of!(VMCallerCheckedAnyfunc, vmctx),
848 usize::from(offsets.vmcaller_checked_anyfunc_vmctx())
849 );
850 }
851}
852
853#[derive(Copy, Clone, Debug)]
855pub struct VMBuiltinFunctionIndex(u32);
856
857impl VMBuiltinFunctionIndex {
858 pub const fn get_memory32_grow_index() -> Self {
860 Self(0)
861 }
862 pub const fn get_imported_memory32_grow_index() -> Self {
864 Self(1)
865 }
866 pub const fn get_memory32_size_index() -> Self {
868 Self(2)
869 }
870 pub const fn get_imported_memory32_size_index() -> Self {
872 Self(3)
873 }
874 pub const fn get_table_copy_index() -> Self {
877 Self(4)
878 }
879 pub const fn get_table_init_index() -> Self {
881 Self(5)
882 }
883 pub const fn get_elem_drop_index() -> Self {
885 Self(6)
886 }
887 pub const fn get_memory_copy_index() -> Self {
889 Self(7)
890 }
891 pub const fn get_imported_memory_copy_index() -> Self {
893 Self(8)
894 }
895 pub const fn get_memory_fill_index() -> Self {
897 Self(9)
898 }
899 pub const fn get_imported_memory_fill_index() -> Self {
901 Self(10)
902 }
903 pub const fn get_memory_init_index() -> Self {
905 Self(11)
906 }
907 pub const fn get_data_drop_index() -> Self {
909 Self(12)
910 }
911 pub const fn get_raise_trap_index() -> Self {
913 Self(13)
914 }
915 pub const fn get_table_size_index() -> Self {
917 Self(14)
918 }
919 pub const fn get_imported_table_size_index() -> Self {
921 Self(15)
922 }
923 pub const fn get_table_grow_index() -> Self {
925 Self(16)
926 }
927 pub const fn get_imported_table_grow_index() -> Self {
929 Self(17)
930 }
931 pub const fn get_table_get_index() -> Self {
933 Self(18)
934 }
935 pub const fn get_imported_table_get_index() -> Self {
937 Self(19)
938 }
939 pub const fn get_table_set_index() -> Self {
941 Self(20)
942 }
943 pub const fn get_imported_table_set_index() -> Self {
945 Self(21)
946 }
947 pub const fn get_func_ref_index() -> Self {
949 Self(22)
950 }
951 pub const fn get_table_fill_index() -> Self {
953 Self(23)
954 }
955 pub const fn get_externref_inc_index() -> Self {
957 Self(24)
958 }
959 pub const fn get_externref_dec_index() -> Self {
961 Self(25)
962 }
963 pub const fn builtin_functions_total_number() -> u32 {
965 26
966 }
967
968 pub const fn index(self) -> u32 {
970 self.0
971 }
972}
973
974#[repr(C)]
977pub struct VMBuiltinFunctionsArray {
978 ptrs: [usize; Self::len()],
979}
980
981impl VMBuiltinFunctionsArray {
982 pub const fn len() -> usize {
983 VMBuiltinFunctionIndex::builtin_functions_total_number() as usize
984 }
985
986 pub fn initialized() -> Self {
987 use crate::libcalls::*;
988
989 let mut ptrs = [0; Self::len()];
990
991 ptrs[VMBuiltinFunctionIndex::get_memory32_grow_index().index() as usize] =
992 near_vm_memory32_grow as usize;
993 ptrs[VMBuiltinFunctionIndex::get_imported_memory32_grow_index().index() as usize] =
994 near_vm_imported_memory32_grow as usize;
995
996 ptrs[VMBuiltinFunctionIndex::get_memory32_size_index().index() as usize] =
997 near_vm_memory32_size as usize;
998 ptrs[VMBuiltinFunctionIndex::get_imported_memory32_size_index().index() as usize] =
999 near_vm_imported_memory32_size as usize;
1000
1001 ptrs[VMBuiltinFunctionIndex::get_table_copy_index().index() as usize] =
1002 near_vm_table_copy as usize;
1003
1004 ptrs[VMBuiltinFunctionIndex::get_table_init_index().index() as usize] =
1005 near_vm_table_init as usize;
1006 ptrs[VMBuiltinFunctionIndex::get_elem_drop_index().index() as usize] =
1007 near_vm_elem_drop as usize;
1008
1009 ptrs[VMBuiltinFunctionIndex::get_memory_copy_index().index() as usize] =
1010 near_vm_memory32_copy as usize;
1011 ptrs[VMBuiltinFunctionIndex::get_imported_memory_copy_index().index() as usize] =
1012 near_vm_imported_memory32_copy as usize;
1013 ptrs[VMBuiltinFunctionIndex::get_memory_fill_index().index() as usize] =
1014 near_vm_memory32_fill as usize;
1015 ptrs[VMBuiltinFunctionIndex::get_imported_memory_fill_index().index() as usize] =
1016 near_vm_imported_memory32_fill as usize;
1017 ptrs[VMBuiltinFunctionIndex::get_memory_init_index().index() as usize] =
1018 near_vm_memory32_init as usize;
1019 ptrs[VMBuiltinFunctionIndex::get_data_drop_index().index() as usize] =
1020 near_vm_data_drop as usize;
1021 ptrs[VMBuiltinFunctionIndex::get_raise_trap_index().index() as usize] =
1022 near_vm_raise_trap as usize;
1023 ptrs[VMBuiltinFunctionIndex::get_table_size_index().index() as usize] =
1024 near_vm_table_size as usize;
1025 ptrs[VMBuiltinFunctionIndex::get_imported_table_size_index().index() as usize] =
1026 near_vm_imported_table_size as usize;
1027 ptrs[VMBuiltinFunctionIndex::get_table_grow_index().index() as usize] =
1028 near_vm_table_grow as usize;
1029 ptrs[VMBuiltinFunctionIndex::get_imported_table_grow_index().index() as usize] =
1030 near_vm_imported_table_grow as usize;
1031 ptrs[VMBuiltinFunctionIndex::get_table_get_index().index() as usize] =
1032 near_vm_table_get as usize;
1033 ptrs[VMBuiltinFunctionIndex::get_imported_table_get_index().index() as usize] =
1034 near_vm_imported_table_get as usize;
1035 ptrs[VMBuiltinFunctionIndex::get_table_set_index().index() as usize] =
1036 near_vm_table_set as usize;
1037 ptrs[VMBuiltinFunctionIndex::get_imported_table_set_index().index() as usize] =
1038 near_vm_imported_table_set as usize;
1039 ptrs[VMBuiltinFunctionIndex::get_func_ref_index().index() as usize] =
1040 near_vm_func_ref as usize;
1041 ptrs[VMBuiltinFunctionIndex::get_table_fill_index().index() as usize] =
1042 near_vm_table_fill as usize;
1043 ptrs[VMBuiltinFunctionIndex::get_externref_inc_index().index() as usize] =
1044 near_vm_externref_inc as usize;
1045 ptrs[VMBuiltinFunctionIndex::get_externref_dec_index().index() as usize] =
1046 near_vm_externref_dec as usize;
1047
1048 debug_assert!(ptrs.iter().cloned().all(|p| p != 0));
1049
1050 Self { ptrs }
1051 }
1052}
1053
1054#[derive(Debug)]
1064#[repr(C, align(16))] pub struct VMContext {}
1066
1067impl VMContext {
1068 #[allow(clippy::cast_ptr_alignment)]
1074 #[inline]
1075 pub unsafe fn instance(&self) -> &Instance {
1076 &*((self as *const Self as *mut u8).offset(-Instance::vmctx_offset()) as *const Instance)
1077 }
1078
1079 #[inline]
1085 pub unsafe fn host_state(&self) -> &dyn Any {
1086 self.instance().host_state()
1087 }
1088}
1089
1090pub type VMTrampoline = unsafe extern "C" fn(
1092 *mut VMContext, *const VMFunctionBody, *mut u128, );
1096
1097#[derive(Clone, Copy, Debug)]
1099#[repr(transparent)]
1100pub struct SectionBodyPtr(pub *const u8);
1101
1102impl std::ops::Deref for SectionBodyPtr {
1103 type Target = *const u8;
1104
1105 fn deref(&self) -> &Self::Target {
1106 &self.0
1107 }
1108}