1#![allow(missing_docs)] use crate::func_data_registry::VMFuncRef;
41use crate::probestack::PROBESTACK;
42use crate::table::{RawTableElement, TableElement};
43use crate::trap::{raise_lib_trap, Trap, TrapCode};
44use crate::vmcontext::VMContext;
45use crate::VMExternRef;
46use std::fmt;
47use wasmer_types::{
48 DataIndex, ElemIndex, FunctionIndex, LocalMemoryIndex, LocalTableIndex, MemoryIndex,
49 TableIndex, Type,
50};
51
52#[no_mangle]
54pub extern "C" fn wasmer_vm_f32_ceil(x: f32) -> f32 {
55 x.ceil()
56}
57
58#[no_mangle]
60pub extern "C" fn wasmer_vm_f32_floor(x: f32) -> f32 {
61 x.floor()
62}
63
64#[no_mangle]
66pub extern "C" fn wasmer_vm_f32_trunc(x: f32) -> f32 {
67 x.trunc()
68}
69
70#[allow(clippy::float_arithmetic, clippy::float_cmp)]
72#[no_mangle]
73pub extern "C" fn wasmer_vm_f32_nearest(x: f32) -> f32 {
74 if x == 0.0 {
76 x
78 } else {
79 let u = x.ceil();
81 let d = x.floor();
82 let um = (x - u).abs();
83 let dm = (x - d).abs();
84 if um < dm
85 || (um == dm && {
86 let h = u / 2.;
87 h.floor() == h
88 })
89 {
90 u
91 } else {
92 d
93 }
94 }
95}
96
97#[no_mangle]
99pub extern "C" fn wasmer_vm_f64_ceil(x: f64) -> f64 {
100 x.ceil()
101}
102
103#[no_mangle]
105pub extern "C" fn wasmer_vm_f64_floor(x: f64) -> f64 {
106 x.floor()
107}
108
109#[no_mangle]
111pub extern "C" fn wasmer_vm_f64_trunc(x: f64) -> f64 {
112 x.trunc()
113}
114
115#[allow(clippy::float_arithmetic, clippy::float_cmp)]
117#[no_mangle]
118pub extern "C" fn wasmer_vm_f64_nearest(x: f64) -> f64 {
119 if x == 0.0 {
121 x
123 } else {
124 let u = x.ceil();
126 let d = x.floor();
127 let um = (x - u).abs();
128 let dm = (x - d).abs();
129 if um < dm
130 || (um == dm && {
131 let h = u / 2.;
132 h.floor() == h
133 })
134 {
135 u
136 } else {
137 d
138 }
139 }
140}
141
142#[no_mangle]
148pub unsafe extern "C" fn wasmer_vm_memory32_grow(
149 vmctx: *mut VMContext,
150 delta: u32,
151 memory_index: u32,
152) -> u32 {
153 let instance = (&*vmctx).instance();
154 let memory_index = LocalMemoryIndex::from_u32(memory_index);
155
156 instance
157 .memory_grow(memory_index, delta)
158 .map(|pages| pages.0)
159 .unwrap_or(u32::max_value())
160}
161
162#[no_mangle]
168pub unsafe extern "C" fn wasmer_vm_imported_memory32_grow(
169 vmctx: *mut VMContext,
170 delta: u32,
171 memory_index: u32,
172) -> u32 {
173 let instance = (&*vmctx).instance();
174 let memory_index = MemoryIndex::from_u32(memory_index);
175
176 instance
177 .imported_memory_grow(memory_index, delta)
178 .map(|pages| pages.0)
179 .unwrap_or(u32::max_value())
180}
181
182#[no_mangle]
188pub unsafe extern "C" fn wasmer_vm_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 {
189 let instance = (&*vmctx).instance();
190 let memory_index = LocalMemoryIndex::from_u32(memory_index);
191
192 instance.memory_size(memory_index).0
193}
194
195#[no_mangle]
201pub unsafe extern "C" fn wasmer_vm_imported_memory32_size(
202 vmctx: *mut VMContext,
203 memory_index: u32,
204) -> u32 {
205 let instance = (&*vmctx).instance();
206 let memory_index = MemoryIndex::from_u32(memory_index);
207
208 instance.imported_memory_size(memory_index).0
209}
210
211#[no_mangle]
217pub unsafe extern "C" fn wasmer_vm_table_copy(
218 vmctx: *mut VMContext,
219 dst_table_index: u32,
220 src_table_index: u32,
221 dst: u32,
222 src: u32,
223 len: u32,
224) {
225 let result = {
226 let dst_table_index = TableIndex::from_u32(dst_table_index);
227 let src_table_index = TableIndex::from_u32(src_table_index);
228 let instance = (&*vmctx).instance();
229 let dst_table = instance.get_table(dst_table_index);
230 let src_table = instance.get_table(src_table_index);
231 dst_table.copy(src_table, dst, src, len)
232 };
233 if let Err(trap) = result {
234 raise_lib_trap(trap);
235 }
236}
237
238#[no_mangle]
244pub unsafe extern "C" fn wasmer_vm_table_init(
245 vmctx: *mut VMContext,
246 table_index: u32,
247 elem_index: u32,
248 dst: u32,
249 src: u32,
250 len: u32,
251) {
252 let result = {
253 let table_index = TableIndex::from_u32(table_index);
254 let elem_index = ElemIndex::from_u32(elem_index);
255 let instance = (&*vmctx).instance();
256 instance.table_init(table_index, elem_index, dst, src, len)
257 };
258 if let Err(trap) = result {
259 raise_lib_trap(trap);
260 }
261}
262
263#[no_mangle]
269pub unsafe extern "C" fn wasmer_vm_table_fill(
270 vmctx: *mut VMContext,
271 table_index: u32,
272 start_idx: u32,
273 item: RawTableElement,
274 len: u32,
275) {
276 let result = {
277 let table_index = TableIndex::from_u32(table_index);
278 let instance = (&*vmctx).instance();
279 let elem = match instance.get_table(table_index).ty().ty {
280 Type::ExternRef => TableElement::ExternRef(item.extern_ref.into()),
281 Type::FuncRef => TableElement::FuncRef(item.func_ref),
282 _ => panic!("Unrecognized table type: does not contain references"),
283 };
284
285 instance.table_fill(table_index, start_idx, elem, len)
286 };
287 if let Err(trap) = result {
288 raise_lib_trap(trap);
289 }
290}
291
292#[no_mangle]
298pub unsafe extern "C" fn wasmer_vm_table_size(vmctx: *mut VMContext, table_index: u32) -> u32 {
299 let instance = (&*vmctx).instance();
300 let table_index = LocalTableIndex::from_u32(table_index);
301
302 instance.table_size(table_index)
303}
304
305#[no_mangle]
311pub unsafe extern "C" fn wasmer_vm_imported_table_size(
312 vmctx: *mut VMContext,
313 table_index: u32,
314) -> u32 {
315 let instance = (&*vmctx).instance();
316 let table_index = TableIndex::from_u32(table_index);
317
318 instance.imported_table_size(table_index)
319}
320
321#[no_mangle]
327pub unsafe extern "C" fn wasmer_vm_table_get(
328 vmctx: *mut VMContext,
329 table_index: u32,
330 elem_index: u32,
331) -> RawTableElement {
332 let instance = (&*vmctx).instance();
333 let table_index = LocalTableIndex::from_u32(table_index);
334
335 match instance.table_get(table_index, elem_index) {
337 Some(table_ref) => table_ref.into(),
338 None => raise_lib_trap(Trap::lib(TrapCode::TableAccessOutOfBounds)),
339 }
340}
341
342#[no_mangle]
348pub unsafe extern "C" fn wasmer_vm_imported_table_get(
349 vmctx: *mut VMContext,
350 table_index: u32,
351 elem_index: u32,
352) -> RawTableElement {
353 let instance = (&*vmctx).instance();
354 let table_index = TableIndex::from_u32(table_index);
355
356 match instance.imported_table_get(table_index, elem_index) {
358 Some(table_ref) => table_ref.into(),
359 None => raise_lib_trap(Trap::lib(TrapCode::TableAccessOutOfBounds)),
360 }
361}
362
363#[no_mangle]
372pub unsafe extern "C" fn wasmer_vm_table_set(
373 vmctx: *mut VMContext,
374 table_index: u32,
375 elem_index: u32,
376 value: RawTableElement,
377) {
378 let instance = (&*vmctx).instance();
379 let table_index = TableIndex::from_u32(table_index);
380 if let Ok(local_table) = instance
381 .artifact
382 .import_counts()
383 .local_table_index(table_index)
384 {
385 let elem = match instance.get_local_table(local_table).ty().ty {
386 Type::ExternRef => TableElement::ExternRef(value.extern_ref.into()),
387 Type::FuncRef => TableElement::FuncRef(value.func_ref),
388 _ => panic!("Unrecognized table type: does not contain references"),
389 };
390 let result = instance.table_set(local_table, elem_index, elem);
392 if let Err(trap) = result {
393 raise_lib_trap(trap);
394 }
395 } else {
396 panic!("wasmer_vm_imported_table_set should have been called");
397 }
398}
399
400#[no_mangle]
406pub unsafe extern "C" fn wasmer_vm_imported_table_set(
407 vmctx: *mut VMContext,
408 table_index: u32,
409 elem_index: u32,
410 value: RawTableElement,
411) {
412 let instance = (&*vmctx).instance();
413 let table_index = TableIndex::from_u32(table_index);
414 let elem = match instance.get_foreign_table(table_index).ty().ty {
415 Type::ExternRef => TableElement::ExternRef(value.extern_ref.into()),
416 Type::FuncRef => TableElement::FuncRef(value.func_ref),
417 _ => panic!("Unrecognized table type: does not contain references"),
418 };
419 let result = instance.imported_table_set(table_index, elem_index, elem);
420 if let Err(trap) = result {
421 raise_lib_trap(trap);
422 }
423}
424
425#[no_mangle]
431pub unsafe extern "C" fn wasmer_vm_table_grow(
432 vmctx: *mut VMContext,
433 init_value: RawTableElement,
434 delta: u32,
435 table_index: u32,
436) -> u32 {
437 let instance = (&*vmctx).instance();
438 let table_index = LocalTableIndex::from_u32(table_index);
439 let init_value = match instance.get_local_table(table_index).ty().ty {
440 Type::ExternRef => TableElement::ExternRef(init_value.extern_ref.into()),
441 Type::FuncRef => TableElement::FuncRef(init_value.func_ref),
442 _ => panic!("Unrecognized table type: does not contain references"),
443 };
444 instance
445 .table_grow(table_index, delta, init_value)
446 .unwrap_or(u32::max_value())
447}
448
449#[no_mangle]
455pub unsafe extern "C" fn wasmer_vm_imported_table_grow(
456 vmctx: *mut VMContext,
457 init_value: RawTableElement,
458 delta: u32,
459 table_index: u32,
460) -> u32 {
461 let instance = (&*vmctx).instance();
462 let table_index = TableIndex::from_u32(table_index);
463 let init_value = match instance.get_table(table_index).ty().ty {
464 Type::ExternRef => TableElement::ExternRef(init_value.extern_ref.into()),
465 Type::FuncRef => TableElement::FuncRef(init_value.func_ref),
466 _ => panic!("Unrecognized table type: does not contain references"),
467 };
468
469 instance
470 .imported_table_grow(table_index, delta, init_value)
471 .unwrap_or(u32::max_value())
472}
473
474#[no_mangle]
480pub unsafe extern "C" fn wasmer_vm_func_ref(
481 vmctx: *mut VMContext,
482 function_index: u32,
483) -> VMFuncRef {
484 let instance = (&*vmctx).instance();
485 let function_index = FunctionIndex::from_u32(function_index);
486
487 instance.func_ref(function_index).unwrap()
488}
489
490#[no_mangle]
498pub unsafe extern "C" fn wasmer_vm_externref_inc(externref: VMExternRef) {
499 externref.ref_clone();
500}
501
502#[no_mangle]
511pub unsafe extern "C" fn wasmer_vm_externref_dec(mut externref: VMExternRef) {
512 externref.ref_drop()
513}
514
515#[no_mangle]
521pub unsafe extern "C" fn wasmer_vm_elem_drop(vmctx: *mut VMContext, elem_index: u32) {
522 let elem_index = ElemIndex::from_u32(elem_index);
523 let instance = (&*vmctx).instance();
524 instance.elem_drop(elem_index);
525}
526
527#[no_mangle]
533pub unsafe extern "C" fn wasmer_vm_memory32_copy(
534 vmctx: *mut VMContext,
535 memory_index: u32,
536 dst: u32,
537 src: u32,
538 len: u32,
539) {
540 let result = {
541 let memory_index = LocalMemoryIndex::from_u32(memory_index);
542 let instance = (&*vmctx).instance();
543 instance.local_memory_copy(memory_index, dst, src, len)
544 };
545 if let Err(trap) = result {
546 raise_lib_trap(trap);
547 }
548}
549
550#[no_mangle]
556pub unsafe extern "C" fn wasmer_vm_imported_memory32_copy(
557 vmctx: *mut VMContext,
558 memory_index: u32,
559 dst: u32,
560 src: u32,
561 len: u32,
562) {
563 let result = {
564 let memory_index = MemoryIndex::from_u32(memory_index);
565 let instance = (&*vmctx).instance();
566 instance.imported_memory_copy(memory_index, dst, src, len)
567 };
568 if let Err(trap) = result {
569 raise_lib_trap(trap);
570 }
571}
572
573#[no_mangle]
579pub unsafe extern "C" fn wasmer_vm_memory32_fill(
580 vmctx: *mut VMContext,
581 memory_index: u32,
582 dst: u32,
583 val: u32,
584 len: u32,
585) {
586 let result = {
587 let memory_index = LocalMemoryIndex::from_u32(memory_index);
588 let instance = (&*vmctx).instance();
589 instance.local_memory_fill(memory_index, dst, val, len)
590 };
591 if let Err(trap) = result {
592 raise_lib_trap(trap);
593 }
594}
595
596#[no_mangle]
602pub unsafe extern "C" fn wasmer_vm_imported_memory32_fill(
603 vmctx: *mut VMContext,
604 memory_index: u32,
605 dst: u32,
606 val: u32,
607 len: u32,
608) {
609 let result = {
610 let memory_index = MemoryIndex::from_u32(memory_index);
611 let instance = (&*vmctx).instance();
612 instance.imported_memory_fill(memory_index, dst, val, len)
613 };
614 if let Err(trap) = result {
615 raise_lib_trap(trap);
616 }
617}
618
619#[no_mangle]
625pub unsafe extern "C" fn wasmer_vm_memory32_init(
626 vmctx: *mut VMContext,
627 memory_index: u32,
628 data_index: u32,
629 dst: u32,
630 src: u32,
631 len: u32,
632) {
633 let result = {
634 let memory_index = MemoryIndex::from_u32(memory_index);
635 let data_index = DataIndex::from_u32(data_index);
636 let instance = (&*vmctx).instance();
637 instance.memory_init(memory_index, data_index, dst, src, len)
638 };
639 if let Err(trap) = result {
640 raise_lib_trap(trap);
641 }
642}
643
644#[no_mangle]
650pub unsafe extern "C" fn wasmer_vm_data_drop(vmctx: *mut VMContext, data_index: u32) {
651 let data_index = DataIndex::from_u32(data_index);
652 let instance = (&*vmctx).instance();
653 instance.data_drop(data_index)
654}
655
656#[no_mangle]
663pub unsafe extern "C" fn wasmer_vm_raise_trap(trap_code: TrapCode) -> ! {
664 let trap = Trap::lib(trap_code);
665 raise_lib_trap(trap)
666}
667
668#[no_mangle]
675pub static wasmer_vm_probestack: unsafe extern "C" fn() = PROBESTACK;
676
677#[derive(
681 rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Copy, Clone, Debug, PartialEq, Eq, Hash,
682)]
683pub enum LibCall {
684 CeilF32,
686
687 CeilF64,
689
690 FloorF32,
692
693 FloorF64,
695
696 NearestF32,
698
699 NearestF64,
701
702 TruncF32,
704
705 TruncF64,
707
708 Memory32Size,
710
711 ImportedMemory32Size,
713
714 TableCopy,
716
717 TableInit,
719
720 TableFill,
722
723 TableSize,
725
726 ImportedTableSize,
728
729 TableGet,
731
732 ImportedTableGet,
734
735 TableSet,
737
738 ImportedTableSet,
740
741 TableGrow,
743
744 ImportedTableGrow,
746
747 FuncRef,
749
750 ElemDrop,
752
753 Memory32Copy,
755
756 ImportedMemory32Copy,
758
759 Memory32Fill,
761
762 ImportedMemory32Fill,
764
765 Memory32Init,
767
768 DataDrop,
770
771 RaiseTrap,
773
774 Probestack,
777}
778
779impl LibCall {
780 pub fn function_pointer(self) -> usize {
782 match self {
783 Self::CeilF32 => wasmer_vm_f32_ceil as usize,
784 Self::CeilF64 => wasmer_vm_f64_ceil as usize,
785 Self::FloorF32 => wasmer_vm_f32_floor as usize,
786 Self::FloorF64 => wasmer_vm_f64_floor as usize,
787 Self::NearestF32 => wasmer_vm_f32_nearest as usize,
788 Self::NearestF64 => wasmer_vm_f64_nearest as usize,
789 Self::TruncF32 => wasmer_vm_f32_trunc as usize,
790 Self::TruncF64 => wasmer_vm_f64_trunc as usize,
791 Self::Memory32Size => wasmer_vm_memory32_size as usize,
792 Self::ImportedMemory32Size => wasmer_vm_imported_memory32_size as usize,
793 Self::TableCopy => wasmer_vm_table_copy as usize,
794 Self::TableInit => wasmer_vm_table_init as usize,
795 Self::TableFill => wasmer_vm_table_fill as usize,
796 Self::TableSize => wasmer_vm_table_size as usize,
797 Self::ImportedTableSize => wasmer_vm_imported_table_size as usize,
798 Self::TableGet => wasmer_vm_table_get as usize,
799 Self::ImportedTableGet => wasmer_vm_imported_table_get as usize,
800 Self::TableSet => wasmer_vm_table_set as usize,
801 Self::ImportedTableSet => wasmer_vm_imported_table_set as usize,
802 Self::TableGrow => wasmer_vm_table_grow as usize,
803 Self::ImportedTableGrow => wasmer_vm_imported_table_grow as usize,
804 Self::FuncRef => wasmer_vm_func_ref as usize,
805 Self::ElemDrop => wasmer_vm_elem_drop as usize,
806 Self::Memory32Copy => wasmer_vm_memory32_copy as usize,
807 Self::ImportedMemory32Copy => wasmer_vm_imported_memory32_copy as usize,
808 Self::Memory32Fill => wasmer_vm_memory32_fill as usize,
809 Self::ImportedMemory32Fill => wasmer_vm_memory32_fill as usize,
810 Self::Memory32Init => wasmer_vm_memory32_init as usize,
811 Self::DataDrop => wasmer_vm_data_drop as usize,
812 Self::Probestack => wasmer_vm_probestack as usize,
813 Self::RaiseTrap => wasmer_vm_raise_trap as usize,
814 }
815 }
816
817 pub fn to_function_name(&self) -> &str {
819 match self {
820 Self::CeilF32 => "wasmer_vm_f32_ceil",
821 Self::CeilF64 => "wasmer_vm_f64_ceil",
822 Self::FloorF32 => "wasmer_vm_f32_floor",
823 Self::FloorF64 => "wasmer_vm_f64_floor",
824 Self::NearestF32 => "wasmer_vm_f32_nearest",
825 Self::NearestF64 => "wasmer_vm_f64_nearest",
826 Self::TruncF32 => "wasmer_vm_f32_trunc",
827 Self::TruncF64 => "wasmer_vm_f64_trunc",
828 Self::Memory32Size => "wasmer_vm_memory32_size",
829 Self::ImportedMemory32Size => "wasmer_vm_imported_memory32_size",
830 Self::TableCopy => "wasmer_vm_table_copy",
831 Self::TableInit => "wasmer_vm_table_init",
832 Self::TableFill => "wasmer_vm_table_fill",
833 Self::TableSize => "wasmer_vm_table_size",
834 Self::ImportedTableSize => "wasmer_vm_imported_table_size",
835 Self::TableGet => "wasmer_vm_table_get",
836 Self::ImportedTableGet => "wasmer_vm_imported_table_get",
837 Self::TableSet => "wasmer_vm_table_set",
838 Self::ImportedTableSet => "wasmer_vm_imported_table_set",
839 Self::TableGrow => "wasmer_vm_table_grow",
840 Self::ImportedTableGrow => "wasmer_vm_imported_table_grow",
841 Self::FuncRef => "wasmer_vm_func_ref",
842 Self::ElemDrop => "wasmer_vm_elem_drop",
843 Self::Memory32Copy => "wasmer_vm_memory32_copy",
844 Self::ImportedMemory32Copy => "wasmer_vm_imported_memory32_copy",
845 Self::Memory32Fill => "wasmer_vm_memory32_fill",
846 Self::ImportedMemory32Fill => "wasmer_vm_imported_memory32_fill",
847 Self::Memory32Init => "wasmer_vm_memory32_init",
848 Self::DataDrop => "wasmer_vm_data_drop",
849 Self::RaiseTrap => "wasmer_vm_raise_trap",
850 #[cfg(target_vendor = "apple")]
853 Self::Probestack => "_wasmer_vm_probestack",
854 #[cfg(not(target_vendor = "apple"))]
855 Self::Probestack => "wasmer_vm_probestack",
856 }
857 }
858}
859
860impl fmt::Display for LibCall {
861 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
862 fmt::Debug::fmt(self, f)
863 }
864}