1use crate::VMExternRef;
8use crate::func_data_registry::VMFuncRef;
9use crate::global::Global;
10use crate::instance::Instance;
11use crate::memory::LinearMemory;
12use crate::sig_registry::VMSharedSignatureIndex;
13use crate::table::Table;
14use crate::trap::{Trap, TrapCode};
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        unsafe {
414            let dst = self.base.add(dst);
415            let src = self.base.add(src);
416            ptr::copy(src, dst, len as usize);
417        }
418
419        Ok(())
420    }
421
422    pub(crate) unsafe fn memory_fill(&self, dst: u32, val: u32, len: u32) -> Result<(), Trap> {
433        if dst.checked_add(len).map_or(true, |m| usize::try_from(m).unwrap() > self.current_length)
434        {
435            return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
436        }
437
438        let dst = isize::try_from(dst).unwrap();
439        let val = val as u8;
440
441        unsafe {
443            let dst = self.base.offset(dst);
444            ptr::write_bytes(dst, val, len as usize);
445        }
446
447        Ok(())
448    }
449}
450
451#[cfg(test)]
452mod test_vmmemory_definition {
453    use super::VMMemoryDefinition;
454    use crate::VMOffsets;
455    use memoffset::offset_of;
456    use near_vm_types::ModuleInfo;
457    use std::mem::size_of;
458
459    #[test]
460    fn check_vmmemory_definition_offsets() {
461        let module = ModuleInfo::new();
462        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
463        assert_eq!(
464            size_of::<VMMemoryDefinition>(),
465            usize::from(offsets.size_of_vmmemory_definition())
466        );
467        assert_eq!(
468            offset_of!(VMMemoryDefinition, base),
469            usize::from(offsets.vmmemory_definition_base())
470        );
471        assert_eq!(
472            offset_of!(VMMemoryDefinition, current_length),
473            usize::from(offsets.vmmemory_definition_current_length())
474        );
475    }
476}
477
478#[derive(Debug, Clone, Copy)]
481#[repr(C)]
482pub struct VMTableDefinition {
483    pub base: *mut u8,
485
486    pub current_elements: u32,
488}
489
490#[cfg(test)]
491mod test_vmtable_definition {
492    use super::VMTableDefinition;
493    use crate::VMOffsets;
494    use memoffset::offset_of;
495    use near_vm_types::ModuleInfo;
496    use std::mem::size_of;
497
498    #[test]
499    fn check_vmtable_definition_offsets() {
500        let module = ModuleInfo::new();
501        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
502        assert_eq!(
503            size_of::<VMTableDefinition>(),
504            usize::from(offsets.size_of_vmtable_definition())
505        );
506        assert_eq!(
507            offset_of!(VMTableDefinition, base),
508            usize::from(offsets.vmtable_definition_base())
509        );
510        assert_eq!(
511            offset_of!(VMTableDefinition, current_elements),
512            usize::from(offsets.vmtable_definition_current_elements())
513        );
514    }
515}
516
517#[derive(Clone, Copy)]
525#[repr(C, align(16))]
526pub union VMGlobalDefinitionStorage {
527    as_i32: i32,
528    as_u32: u32,
529    as_f32: f32,
530    as_i64: i64,
531    as_u64: u64,
532    as_f64: f64,
533    as_u128: u128,
534    as_funcref: VMFuncRef,
535    as_externref: VMExternRef,
536    bytes: [u8; 16],
537}
538
539impl fmt::Debug for VMGlobalDefinitionStorage {
540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
541        f.debug_struct("VMGlobalDefinitionStorage").field("bytes", unsafe { &self.bytes }).finish()
542    }
543}
544
545#[derive(Debug, Clone)]
550#[repr(C, align(16))]
551pub struct VMGlobalDefinition {
552    storage: VMGlobalDefinitionStorage,
553    }
555
556#[cfg(test)]
557mod test_vmglobal_definition {
558    use super::VMGlobalDefinition;
559    use crate::{VMFuncRef, VMOffsets};
560    use more_asserts::assert_ge;
561    use near_vm_types::ModuleInfo;
562    use std::mem::{align_of, size_of};
563
564    #[test]
565    fn check_vmglobal_definition_alignment() {
566        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<i32>());
567        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<i64>());
568        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<f32>());
569        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<f64>());
570        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<VMFuncRef>());
571        assert_ge!(align_of::<VMGlobalDefinition>(), align_of::<[u8; 16]>());
572    }
573
574    #[test]
575    fn check_vmglobal_definition_offsets() {
576        let module = ModuleInfo::new();
577        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
578        assert_eq!(
579            size_of::<*const VMGlobalDefinition>(),
580            usize::from(offsets.size_of_vmglobal_local())
581        );
582    }
583
584    #[test]
585    fn check_vmglobal_begins_aligned() {
586        let module = ModuleInfo::new();
587        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
588        assert_eq!(offsets.vmctx_globals_begin() % 16, 0);
589    }
590}
591
592impl VMGlobalDefinition {
593    pub fn new() -> Self {
595        Self { storage: VMGlobalDefinitionStorage { bytes: [0; 16] } }
596    }
597
598    pub unsafe fn to_i32(&self) -> i32 {
602        unsafe { self.storage.as_i32 }
603    }
604
605    pub unsafe fn as_i32_mut(&mut self) -> &mut i32 {
614        unsafe { &mut self.storage.as_i32 }
615    }
616
617    pub unsafe fn to_u32(&self) -> u32 {
621        unsafe { self.storage.as_u32 }
622    }
623
624    pub unsafe fn as_u32_mut(&mut self) -> &mut u32 {
633        unsafe { &mut self.storage.as_u32 }
634    }
635
636    pub unsafe fn to_i64(&self) -> i64 {
640        unsafe { self.storage.as_i64 }
641    }
642
643    pub unsafe fn as_i64_mut(&mut self) -> &mut i64 {
652        unsafe { &mut self.storage.as_i64 }
653    }
654
655    pub unsafe fn to_u64(&self) -> u64 {
659        unsafe { self.storage.as_u64 }
660    }
661
662    pub unsafe fn as_u64_mut(&mut self) -> &mut u64 {
671        unsafe { &mut self.storage.as_u64 }
672    }
673
674    pub unsafe fn to_f32(&self) -> f32 {
678        unsafe { self.storage.as_f32 }
679    }
680
681    pub unsafe fn as_f32_mut(&mut self) -> &mut f32 {
690        unsafe { &mut self.storage.as_f32 }
691    }
692
693    pub unsafe fn to_f64(&self) -> f64 {
697        unsafe { self.storage.as_f64 }
698    }
699
700    pub unsafe fn as_f64_mut(&mut self) -> &mut f64 {
709        unsafe { &mut self.storage.as_f64 }
710    }
711
712    pub unsafe fn to_funcref(&self) -> VMFuncRef {
716        unsafe { self.storage.as_funcref }
717    }
718
719    pub unsafe fn as_funcref_mut(&mut self) -> &mut VMFuncRef {
728        unsafe { &mut self.storage.as_funcref }
729    }
730
731    pub unsafe fn as_externref_mut(&mut self) -> &mut VMExternRef {
740        unsafe { &mut self.storage.as_externref }
741    }
742
743    pub unsafe fn to_externref(&self) -> VMExternRef {
747        unsafe { self.storage.as_externref }
748    }
749
750    pub unsafe fn to_u128(&self) -> u128 {
754        unsafe { self.storage.as_u128 }
755    }
756
757    pub unsafe fn as_u128_mut(&mut self) -> &mut u128 {
766        unsafe { &mut self.storage.as_u128 }
767    }
768
769    pub unsafe fn to_bytes(&self) -> [u8; 16] {
771        unsafe { self.storage.bytes }
772    }
773
774    pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8; 16] {
782        unsafe { &mut self.storage.bytes }
783    }
784}
785
786#[cfg(test)]
787mod test_vmshared_signature_index {
788    use super::VMSharedSignatureIndex;
789    use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};
790    use near_vm_types::ModuleInfo;
791    use std::mem::size_of;
792
793    #[test]
794    fn check_vmshared_signature_index() {
795        let module = ModuleInfo::new();
796        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
797        assert_eq!(
798            size_of::<VMSharedSignatureIndex>(),
799            usize::from(offsets.size_of_vmshared_signature_index())
800        );
801    }
802
803    #[test]
804    fn check_target_shared_signature_index() {
805        assert_eq!(size_of::<VMSharedSignatureIndex>(), size_of::<TargetSharedSignatureIndex>());
806    }
807}
808
809#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
813#[repr(C)]
814pub struct VMCallerCheckedAnyfunc {
815    pub func_ptr: *const VMFunctionBody,
817    pub type_index: VMSharedSignatureIndex,
819    pub vmctx: VMFunctionEnvironment,
821    }
823
824#[cfg(test)]
825mod test_vmcaller_checked_anyfunc {
826    use super::VMCallerCheckedAnyfunc;
827    use crate::VMOffsets;
828    use memoffset::offset_of;
829    use near_vm_types::ModuleInfo;
830    use std::mem::size_of;
831
832    #[test]
833    fn check_vmcaller_checked_anyfunc_offsets() {
834        let module = ModuleInfo::new();
835        let offsets = VMOffsets::new(size_of::<*mut u8>() as u8).with_module_info(&module);
836        assert_eq!(
837            size_of::<VMCallerCheckedAnyfunc>(),
838            usize::from(offsets.size_of_vmcaller_checked_anyfunc())
839        );
840        assert_eq!(
841            offset_of!(VMCallerCheckedAnyfunc, func_ptr),
842            usize::from(offsets.vmcaller_checked_anyfunc_func_ptr())
843        );
844        assert_eq!(
845            offset_of!(VMCallerCheckedAnyfunc, type_index),
846            usize::from(offsets.vmcaller_checked_anyfunc_type_index())
847        );
848        assert_eq!(
849            offset_of!(VMCallerCheckedAnyfunc, vmctx),
850            usize::from(offsets.vmcaller_checked_anyfunc_vmctx())
851        );
852    }
853}
854
855#[derive(Copy, Clone, Debug)]
857pub struct VMBuiltinFunctionIndex(u32);
858
859impl VMBuiltinFunctionIndex {
860    pub const fn get_memory32_grow_index() -> Self {
862        Self(0)
863    }
864    pub const fn get_imported_memory32_grow_index() -> Self {
866        Self(1)
867    }
868    pub const fn get_memory32_size_index() -> Self {
870        Self(2)
871    }
872    pub const fn get_imported_memory32_size_index() -> Self {
874        Self(3)
875    }
876    pub const fn get_table_copy_index() -> Self {
879        Self(4)
880    }
881    pub const fn get_table_init_index() -> Self {
883        Self(5)
884    }
885    pub const fn get_elem_drop_index() -> Self {
887        Self(6)
888    }
889    pub const fn get_memory_copy_index() -> Self {
891        Self(7)
892    }
893    pub const fn get_imported_memory_copy_index() -> Self {
895        Self(8)
896    }
897    pub const fn get_memory_fill_index() -> Self {
899        Self(9)
900    }
901    pub const fn get_imported_memory_fill_index() -> Self {
903        Self(10)
904    }
905    pub const fn get_memory_init_index() -> Self {
907        Self(11)
908    }
909    pub const fn get_data_drop_index() -> Self {
911        Self(12)
912    }
913    pub const fn get_raise_trap_index() -> Self {
915        Self(13)
916    }
917    pub const fn get_table_size_index() -> Self {
919        Self(14)
920    }
921    pub const fn get_imported_table_size_index() -> Self {
923        Self(15)
924    }
925    pub const fn get_table_grow_index() -> Self {
927        Self(16)
928    }
929    pub const fn get_imported_table_grow_index() -> Self {
931        Self(17)
932    }
933    pub const fn get_table_get_index() -> Self {
935        Self(18)
936    }
937    pub const fn get_imported_table_get_index() -> Self {
939        Self(19)
940    }
941    pub const fn get_table_set_index() -> Self {
943        Self(20)
944    }
945    pub const fn get_imported_table_set_index() -> Self {
947        Self(21)
948    }
949    pub const fn get_func_ref_index() -> Self {
951        Self(22)
952    }
953    pub const fn get_table_fill_index() -> Self {
955        Self(23)
956    }
957    pub const fn get_externref_inc_index() -> Self {
959        Self(24)
960    }
961    pub const fn get_externref_dec_index() -> Self {
963        Self(25)
964    }
965    pub const fn builtin_functions_total_number() -> u32 {
967        26
968    }
969
970    pub const fn index(self) -> u32 {
972        self.0
973    }
974}
975
976#[repr(C)]
979pub struct VMBuiltinFunctionsArray {
980    ptrs: [usize; Self::len()],
981}
982
983impl VMBuiltinFunctionsArray {
984    pub const fn len() -> usize {
985        VMBuiltinFunctionIndex::builtin_functions_total_number() as usize
986    }
987
988    pub fn initialized() -> Self {
989        use crate::libcalls::*;
990
991        let mut ptrs = [0; Self::len()];
992
993        ptrs[VMBuiltinFunctionIndex::get_memory32_grow_index().index() as usize] =
994            near_vm_memory32_grow as usize;
995        ptrs[VMBuiltinFunctionIndex::get_imported_memory32_grow_index().index() as usize] =
996            near_vm_imported_memory32_grow as usize;
997
998        ptrs[VMBuiltinFunctionIndex::get_memory32_size_index().index() as usize] =
999            near_vm_memory32_size as usize;
1000        ptrs[VMBuiltinFunctionIndex::get_imported_memory32_size_index().index() as usize] =
1001            near_vm_imported_memory32_size as usize;
1002
1003        ptrs[VMBuiltinFunctionIndex::get_table_copy_index().index() as usize] =
1004            near_vm_table_copy as usize;
1005
1006        ptrs[VMBuiltinFunctionIndex::get_table_init_index().index() as usize] =
1007            near_vm_table_init as usize;
1008        ptrs[VMBuiltinFunctionIndex::get_elem_drop_index().index() as usize] =
1009            near_vm_elem_drop as usize;
1010
1011        ptrs[VMBuiltinFunctionIndex::get_memory_copy_index().index() as usize] =
1012            near_vm_memory32_copy as usize;
1013        ptrs[VMBuiltinFunctionIndex::get_imported_memory_copy_index().index() as usize] =
1014            near_vm_imported_memory32_copy as usize;
1015        ptrs[VMBuiltinFunctionIndex::get_memory_fill_index().index() as usize] =
1016            near_vm_memory32_fill as usize;
1017        ptrs[VMBuiltinFunctionIndex::get_imported_memory_fill_index().index() as usize] =
1018            near_vm_imported_memory32_fill as usize;
1019        ptrs[VMBuiltinFunctionIndex::get_memory_init_index().index() as usize] =
1020            near_vm_memory32_init as usize;
1021        ptrs[VMBuiltinFunctionIndex::get_data_drop_index().index() as usize] =
1022            near_vm_data_drop as usize;
1023        ptrs[VMBuiltinFunctionIndex::get_raise_trap_index().index() as usize] =
1024            near_vm_raise_trap as usize;
1025        ptrs[VMBuiltinFunctionIndex::get_table_size_index().index() as usize] =
1026            near_vm_table_size as usize;
1027        ptrs[VMBuiltinFunctionIndex::get_imported_table_size_index().index() as usize] =
1028            near_vm_imported_table_size as usize;
1029        ptrs[VMBuiltinFunctionIndex::get_table_grow_index().index() as usize] =
1030            near_vm_table_grow as usize;
1031        ptrs[VMBuiltinFunctionIndex::get_imported_table_grow_index().index() as usize] =
1032            near_vm_imported_table_grow as usize;
1033        ptrs[VMBuiltinFunctionIndex::get_table_get_index().index() as usize] =
1034            near_vm_table_get as usize;
1035        ptrs[VMBuiltinFunctionIndex::get_imported_table_get_index().index() as usize] =
1036            near_vm_imported_table_get as usize;
1037        ptrs[VMBuiltinFunctionIndex::get_table_set_index().index() as usize] =
1038            near_vm_table_set as usize;
1039        ptrs[VMBuiltinFunctionIndex::get_imported_table_set_index().index() as usize] =
1040            near_vm_imported_table_set as usize;
1041        ptrs[VMBuiltinFunctionIndex::get_func_ref_index().index() as usize] =
1042            near_vm_func_ref as usize;
1043        ptrs[VMBuiltinFunctionIndex::get_table_fill_index().index() as usize] =
1044            near_vm_table_fill as usize;
1045        ptrs[VMBuiltinFunctionIndex::get_externref_inc_index().index() as usize] =
1046            near_vm_externref_inc as usize;
1047        ptrs[VMBuiltinFunctionIndex::get_externref_dec_index().index() as usize] =
1048            near_vm_externref_dec as usize;
1049
1050        debug_assert!(ptrs.iter().cloned().all(|p| p != 0));
1051
1052        Self { ptrs }
1053    }
1054}
1055
1056#[derive(Debug)]
1066#[repr(C, align(16))] pub struct VMContext {}
1068
1069impl VMContext {
1070    #[allow(clippy::cast_ptr_alignment)]
1076    #[inline]
1077    pub unsafe fn instance(&self) -> &Instance {
1078        unsafe { &*((self as *const Self as *mut u8).offset(-Instance::vmctx_offset()).cast()) }
1079    }
1080
1081    #[inline]
1087    pub unsafe fn host_state(&self) -> &dyn Any {
1088        unsafe { self.instance().host_state() }
1089    }
1090}
1091
1092pub type VMTrampoline = unsafe extern "C" fn(
1094    *mut VMContext,        *const VMFunctionBody, *mut u128,             );
1098
1099#[derive(Clone, Copy, Debug)]
1101#[repr(transparent)]
1102pub struct SectionBodyPtr(pub *const u8);
1103
1104impl std::ops::Deref for SectionBodyPtr {
1105    type Target = *const u8;
1106
1107    fn deref(&self) -> &Self::Target {
1108        &self.0
1109    }
1110}