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}