1#![allow(missing_docs)] use crate::probestack::PROBESTACK;
41use crate::table::{RawTableElement, TableElement};
42use crate::trap::{raise_lib_trap, Trap, TrapCode};
43use crate::vmcontext::VMContext;
44use crate::{on_host_stack, VMFuncRef};
45pub use wasmer_types::LibCall;
46use wasmer_types::{
47 DataIndex, ElemIndex, FunctionIndex, LocalMemoryIndex, LocalTableIndex, MemoryIndex,
48 TableIndex, Type,
49};
50
51#[no_mangle]
53pub extern "C" fn wasmer_vm_f32_ceil(x: f32) -> f32 {
54 x.ceil()
55}
56
57#[no_mangle]
59pub extern "C" fn wasmer_vm_f32_floor(x: f32) -> f32 {
60 x.floor()
61}
62
63#[no_mangle]
65pub extern "C" fn wasmer_vm_f32_trunc(x: f32) -> f32 {
66 x.trunc()
67}
68
69#[allow(clippy::float_arithmetic, clippy::float_cmp)]
71#[no_mangle]
72pub extern "C" fn wasmer_vm_f32_nearest(x: f32) -> f32 {
73 if x == 0.0 {
75 x
77 } else {
78 let u = x.ceil();
80 let d = x.floor();
81 let um = (x - u).abs();
82 let dm = (x - d).abs();
83 if um < dm
84 || (um == dm && {
85 let h = u / 2.;
86 h.floor() == h
87 })
88 {
89 u
90 } else {
91 d
92 }
93 }
94}
95
96#[no_mangle]
98pub extern "C" fn wasmer_vm_f64_ceil(x: f64) -> f64 {
99 x.ceil()
100}
101
102#[no_mangle]
104pub extern "C" fn wasmer_vm_f64_floor(x: f64) -> f64 {
105 x.floor()
106}
107
108#[no_mangle]
110pub extern "C" fn wasmer_vm_f64_trunc(x: f64) -> f64 {
111 x.trunc()
112}
113
114#[allow(clippy::float_arithmetic, clippy::float_cmp)]
116#[no_mangle]
117pub extern "C" fn wasmer_vm_f64_nearest(x: f64) -> f64 {
118 if x == 0.0 {
120 x
122 } else {
123 let u = x.ceil();
125 let d = x.floor();
126 let um = (x - u).abs();
127 let dm = (x - d).abs();
128 if um < dm
129 || (um == dm && {
130 let h = u / 2.;
131 h.floor() == h
132 })
133 {
134 u
135 } else {
136 d
137 }
138 }
139}
140
141#[no_mangle]
147pub unsafe extern "C" fn wasmer_vm_memory32_grow(
148 vmctx: *mut VMContext,
149 delta: u32,
150 memory_index: u32,
151) -> u32 {
152 on_host_stack(|| {
153 let instance = (*vmctx).instance_mut();
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)
160 })
161}
162
163#[no_mangle]
169pub unsafe extern "C" fn wasmer_vm_imported_memory32_grow(
170 vmctx: *mut VMContext,
171 delta: u32,
172 memory_index: u32,
173) -> u32 {
174 on_host_stack(|| {
175 let instance = (*vmctx).instance_mut();
176 let memory_index = MemoryIndex::from_u32(memory_index);
177
178 instance
179 .imported_memory_grow(memory_index, delta)
180 .map(|pages| pages.0)
181 .unwrap_or(u32::MAX)
182 })
183}
184
185#[no_mangle]
191pub unsafe extern "C" fn wasmer_vm_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 {
192 let instance = (*vmctx).instance();
193 let memory_index = LocalMemoryIndex::from_u32(memory_index);
194
195 instance.memory_size(memory_index).0
196}
197
198#[no_mangle]
204pub unsafe extern "C" fn wasmer_vm_imported_memory32_size(
205 vmctx: *mut VMContext,
206 memory_index: u32,
207) -> u32 {
208 let instance = (*vmctx).instance();
209 let memory_index = MemoryIndex::from_u32(memory_index);
210
211 instance.imported_memory_size(memory_index).0
212}
213
214#[no_mangle]
220pub unsafe extern "C" fn wasmer_vm_table_copy(
221 vmctx: *mut VMContext,
222 dst_table_index: u32,
223 src_table_index: u32,
224 dst: u32,
225 src: u32,
226 len: u32,
227) {
228 let result = {
229 let dst_table_index = TableIndex::from_u32(dst_table_index);
230 let src_table_index = TableIndex::from_u32(src_table_index);
231 if dst_table_index == src_table_index {
232 let table = (*vmctx).instance_mut().get_table(dst_table_index);
233 table.copy_within(dst, src, len)
234 } else {
235 let dst_table = (*vmctx).instance_mut().get_table(dst_table_index);
236 let src_table = (*vmctx).instance_mut().get_table(src_table_index);
237 dst_table.copy(src_table, dst, src, len)
238 }
239 };
240 if let Err(trap) = result {
241 raise_lib_trap(trap);
242 }
243}
244
245#[no_mangle]
251pub unsafe extern "C" fn wasmer_vm_table_init(
252 vmctx: *mut VMContext,
253 table_index: u32,
254 elem_index: u32,
255 dst: u32,
256 src: u32,
257 len: u32,
258) {
259 let result = {
260 let table_index = TableIndex::from_u32(table_index);
261 let elem_index = ElemIndex::from_u32(elem_index);
262 let instance = (*vmctx).instance_mut();
263 instance.table_init(table_index, elem_index, dst, src, len)
264 };
265 if let Err(trap) = result {
266 raise_lib_trap(trap);
267 }
268}
269
270#[no_mangle]
276pub unsafe extern "C" fn wasmer_vm_table_fill(
277 vmctx: *mut VMContext,
278 table_index: u32,
279 start_idx: u32,
280 item: RawTableElement,
281 len: u32,
282) {
283 let result = {
284 let table_index = TableIndex::from_u32(table_index);
285 let instance = (*vmctx).instance_mut();
286 let elem = match instance.get_table(table_index).ty().ty {
287 Type::ExternRef => TableElement::ExternRef(item.extern_ref),
288 Type::FuncRef => TableElement::FuncRef(item.func_ref),
289 _ => panic!("Unrecognized table type: does not contain references"),
290 };
291
292 instance.table_fill(table_index, start_idx, elem, len)
293 };
294 if let Err(trap) = result {
295 raise_lib_trap(trap);
296 }
297}
298
299#[no_mangle]
305pub unsafe extern "C" fn wasmer_vm_table_size(vmctx: *mut VMContext, table_index: u32) -> u32 {
306 let instance = (*vmctx).instance();
307 let table_index = LocalTableIndex::from_u32(table_index);
308
309 instance.table_size(table_index)
310}
311
312#[no_mangle]
318pub unsafe extern "C" fn wasmer_vm_imported_table_size(
319 vmctx: *mut VMContext,
320 table_index: u32,
321) -> u32 {
322 let instance = (*vmctx).instance();
323 let table_index = TableIndex::from_u32(table_index);
324
325 instance.imported_table_size(table_index)
326}
327
328#[no_mangle]
334pub unsafe extern "C" fn wasmer_vm_table_get(
335 vmctx: *mut VMContext,
336 table_index: u32,
337 elem_index: u32,
338) -> RawTableElement {
339 let instance = (*vmctx).instance();
340 let table_index = LocalTableIndex::from_u32(table_index);
341
342 match instance.table_get(table_index, elem_index) {
344 Some(table_ref) => table_ref.into(),
345 None => raise_lib_trap(Trap::lib(TrapCode::TableAccessOutOfBounds)),
346 }
347}
348
349#[no_mangle]
355pub unsafe extern "C" fn wasmer_vm_imported_table_get(
356 vmctx: *mut VMContext,
357 table_index: u32,
358 elem_index: u32,
359) -> RawTableElement {
360 let instance = (*vmctx).instance_mut();
361 let table_index = TableIndex::from_u32(table_index);
362
363 match instance.imported_table_get(table_index, elem_index) {
365 Some(table_ref) => table_ref.into(),
366 None => raise_lib_trap(Trap::lib(TrapCode::TableAccessOutOfBounds)),
367 }
368}
369
370#[no_mangle]
379pub unsafe extern "C" fn wasmer_vm_table_set(
380 vmctx: *mut VMContext,
381 table_index: u32,
382 elem_index: u32,
383 value: RawTableElement,
384) {
385 let instance = (*vmctx).instance_mut();
386 let table_index = TableIndex::from_u32(table_index);
387 let table_index = instance
388 .module_ref()
389 .local_table_index(table_index)
390 .unwrap();
391
392 let elem = match instance.get_local_table(table_index).ty().ty {
393 Type::ExternRef => TableElement::ExternRef(value.extern_ref),
394 Type::FuncRef => TableElement::FuncRef(value.func_ref),
395 _ => panic!("Unrecognized table type: does not contain references"),
396 };
397
398 let result = instance.table_set(table_index, elem_index, elem);
400
401 if let Err(trap) = result {
402 raise_lib_trap(trap);
403 }
404}
405
406#[no_mangle]
412pub unsafe extern "C" fn wasmer_vm_imported_table_set(
413 vmctx: *mut VMContext,
414 table_index: u32,
415 elem_index: u32,
416 value: RawTableElement,
417) {
418 let instance = (*vmctx).instance_mut();
419 let table_index = TableIndex::from_u32(table_index);
420 let elem = match instance.get_table(table_index).ty().ty {
421 Type::ExternRef => TableElement::ExternRef(value.extern_ref),
422 Type::FuncRef => TableElement::FuncRef(value.func_ref),
423 _ => panic!("Unrecognized table type: does not contain references"),
424 };
425
426 let result = instance.imported_table_set(table_index, elem_index, elem);
427
428 if let Err(trap) = result {
429 raise_lib_trap(trap);
430 }
431}
432
433#[no_mangle]
439pub unsafe extern "C" fn wasmer_vm_table_grow(
440 vmctx: *mut VMContext,
441 init_value: RawTableElement,
442 delta: u32,
443 table_index: u32,
444) -> u32 {
445 on_host_stack(|| {
446 let instance = (*vmctx).instance_mut();
447 let table_index = LocalTableIndex::from_u32(table_index);
448
449 let init_value = match instance.get_local_table(table_index).ty().ty {
450 Type::ExternRef => TableElement::ExternRef(init_value.extern_ref),
451 Type::FuncRef => TableElement::FuncRef(init_value.func_ref),
452 _ => panic!("Unrecognized table type: does not contain references"),
453 };
454
455 instance
456 .table_grow(table_index, delta, init_value)
457 .unwrap_or(u32::MAX)
458 })
459}
460
461#[no_mangle]
467pub unsafe extern "C" fn wasmer_vm_imported_table_grow(
468 vmctx: *mut VMContext,
469 init_value: RawTableElement,
470 delta: u32,
471 table_index: u32,
472) -> u32 {
473 on_host_stack(|| {
474 let instance = (*vmctx).instance_mut();
475 let table_index = TableIndex::from_u32(table_index);
476 let init_value = match instance.get_table(table_index).ty().ty {
477 Type::ExternRef => TableElement::ExternRef(init_value.extern_ref),
478 Type::FuncRef => TableElement::FuncRef(init_value.func_ref),
479 _ => panic!("Unrecognized table type: does not contain references"),
480 };
481
482 instance
483 .imported_table_grow(table_index, delta, init_value)
484 .unwrap_or(u32::MAX)
485 })
486}
487
488#[no_mangle]
494pub unsafe extern "C" fn wasmer_vm_func_ref(
495 vmctx: *mut VMContext,
496 function_index: u32,
497) -> VMFuncRef {
498 let instance = (*vmctx).instance();
499 let function_index = FunctionIndex::from_u32(function_index);
500
501 instance.func_ref(function_index).unwrap()
502}
503
504#[no_mangle]
510pub unsafe extern "C" fn wasmer_vm_elem_drop(vmctx: *mut VMContext, elem_index: u32) {
511 on_host_stack(|| {
512 let elem_index = ElemIndex::from_u32(elem_index);
513 let instance = (*vmctx).instance();
514 instance.elem_drop(elem_index);
515 })
516}
517
518#[no_mangle]
524pub unsafe extern "C" fn wasmer_vm_memory32_copy(
525 vmctx: *mut VMContext,
526 memory_index: u32,
527 dst: u32,
528 src: u32,
529 len: u32,
530) {
531 let result = {
532 let memory_index = LocalMemoryIndex::from_u32(memory_index);
533 let instance = (*vmctx).instance();
534 instance.local_memory_copy(memory_index, dst, src, len)
535 };
536 if let Err(trap) = result {
537 raise_lib_trap(trap);
538 }
539}
540
541#[no_mangle]
547pub unsafe extern "C" fn wasmer_vm_imported_memory32_copy(
548 vmctx: *mut VMContext,
549 memory_index: u32,
550 dst: u32,
551 src: u32,
552 len: u32,
553) {
554 let result = {
555 let memory_index = MemoryIndex::from_u32(memory_index);
556 let instance = (*vmctx).instance();
557 instance.imported_memory_copy(memory_index, dst, src, len)
558 };
559 if let Err(trap) = result {
560 raise_lib_trap(trap);
561 }
562}
563
564#[no_mangle]
570pub unsafe extern "C" fn wasmer_vm_memory32_fill(
571 vmctx: *mut VMContext,
572 memory_index: u32,
573 dst: u32,
574 val: u32,
575 len: u32,
576) {
577 let result = {
578 let memory_index = LocalMemoryIndex::from_u32(memory_index);
579 let instance = (*vmctx).instance();
580 instance.local_memory_fill(memory_index, dst, val, len)
581 };
582 if let Err(trap) = result {
583 raise_lib_trap(trap);
584 }
585}
586
587#[no_mangle]
593pub unsafe extern "C" fn wasmer_vm_imported_memory32_fill(
594 vmctx: *mut VMContext,
595 memory_index: u32,
596 dst: u32,
597 val: u32,
598 len: u32,
599) {
600 let result = {
601 let memory_index = MemoryIndex::from_u32(memory_index);
602 let instance = (*vmctx).instance();
603 instance.imported_memory_fill(memory_index, dst, val, len)
604 };
605 if let Err(trap) = result {
606 raise_lib_trap(trap);
607 }
608}
609
610#[no_mangle]
616pub unsafe extern "C" fn wasmer_vm_memory32_init(
617 vmctx: *mut VMContext,
618 memory_index: u32,
619 data_index: u32,
620 dst: u32,
621 src: u32,
622 len: u32,
623) {
624 let result = {
625 let memory_index = MemoryIndex::from_u32(memory_index);
626 let data_index = DataIndex::from_u32(data_index);
627 let instance = (*vmctx).instance();
628 instance.memory_init(memory_index, data_index, dst, src, len)
629 };
630 if let Err(trap) = result {
631 raise_lib_trap(trap);
632 }
633}
634
635#[no_mangle]
641pub unsafe extern "C" fn wasmer_vm_data_drop(vmctx: *mut VMContext, data_index: u32) {
642 on_host_stack(|| {
643 let data_index = DataIndex::from_u32(data_index);
644 let instance = (*vmctx).instance();
645 instance.data_drop(data_index)
646 })
647}
648
649#[no_mangle]
656pub unsafe extern "C" fn wasmer_vm_raise_trap(trap_code: TrapCode) -> ! {
657 let trap = Trap::lib(trap_code);
658 raise_lib_trap(trap)
659}
660
661#[no_mangle]
668pub static wasmer_vm_probestack: unsafe extern "C" fn() = PROBESTACK;
669
670#[no_mangle]
676pub unsafe extern "C" fn wasmer_vm_memory32_atomic_wait32(
677 vmctx: *mut VMContext,
678 memory_index: u32,
679 dst: u32,
680 val: u32,
681 timeout: i64,
682) -> u32 {
683 let result = {
684 let instance = (*vmctx).instance_mut();
685 let memory_index = LocalMemoryIndex::from_u32(memory_index);
686
687 instance.local_memory_wait32(memory_index, dst, val, timeout)
688 };
689 if let Err(trap) = result {
690 raise_lib_trap(trap);
691 }
692 result.unwrap()
693}
694
695#[no_mangle]
701pub unsafe extern "C" fn wasmer_vm_imported_memory32_atomic_wait32(
702 vmctx: *mut VMContext,
703 memory_index: u32,
704 dst: u32,
705 val: u32,
706 timeout: i64,
707) -> u32 {
708 let result = {
709 let instance = (*vmctx).instance_mut();
710 let memory_index = MemoryIndex::from_u32(memory_index);
711
712 instance.imported_memory_wait32(memory_index, dst, val, timeout)
713 };
714 if let Err(trap) = result {
715 raise_lib_trap(trap);
716 }
717 result.unwrap()
718}
719
720#[no_mangle]
726pub unsafe extern "C" fn wasmer_vm_memory32_atomic_wait64(
727 vmctx: *mut VMContext,
728 memory_index: u32,
729 dst: u32,
730 val: u64,
731 timeout: i64,
732) -> u32 {
733 let result = {
734 let instance = (*vmctx).instance_mut();
735 let memory_index = LocalMemoryIndex::from_u32(memory_index);
736
737 instance.local_memory_wait64(memory_index, dst, val, timeout)
738 };
739 if let Err(trap) = result {
740 raise_lib_trap(trap);
741 }
742 result.unwrap()
743}
744
745#[no_mangle]
751pub unsafe extern "C" fn wasmer_vm_imported_memory32_atomic_wait64(
752 vmctx: *mut VMContext,
753 memory_index: u32,
754 dst: u32,
755 val: u64,
756 timeout: i64,
757) -> u32 {
758 let result = {
759 let instance = (*vmctx).instance_mut();
760 let memory_index = MemoryIndex::from_u32(memory_index);
761
762 instance.imported_memory_wait64(memory_index, dst, val, timeout)
763 };
764 if let Err(trap) = result {
765 raise_lib_trap(trap);
766 }
767 result.unwrap()
768}
769
770#[no_mangle]
776pub unsafe extern "C" fn wasmer_vm_memory32_atomic_notify(
777 vmctx: *mut VMContext,
778 memory_index: u32,
779 dst: u32,
780 cnt: u32,
781) -> u32 {
782 let result = {
783 let instance = (*vmctx).instance_mut();
784 let memory_index = LocalMemoryIndex::from_u32(memory_index);
785
786 instance.local_memory_notify(memory_index, dst, cnt)
787 };
788 if let Err(trap) = result {
789 raise_lib_trap(trap);
790 }
791 result.unwrap()
792}
793
794#[no_mangle]
800pub unsafe extern "C" fn wasmer_vm_imported_memory32_atomic_notify(
801 vmctx: *mut VMContext,
802 memory_index: u32,
803 dst: u32,
804 cnt: u32,
805) -> u32 {
806 let result = {
807 let instance = (*vmctx).instance_mut();
808 let memory_index = MemoryIndex::from_u32(memory_index);
809
810 instance.imported_memory_notify(memory_index, dst, cnt)
811 };
812 if let Err(trap) = result {
813 raise_lib_trap(trap);
814 }
815 result.unwrap()
816}
817
818pub fn function_pointer(libcall: LibCall) -> usize {
820 match libcall {
821 LibCall::CeilF32 => wasmer_vm_f32_ceil as usize,
822 LibCall::CeilF64 => wasmer_vm_f64_ceil as usize,
823 LibCall::FloorF32 => wasmer_vm_f32_floor as usize,
824 LibCall::FloorF64 => wasmer_vm_f64_floor as usize,
825 LibCall::NearestF32 => wasmer_vm_f32_nearest as usize,
826 LibCall::NearestF64 => wasmer_vm_f64_nearest as usize,
827 LibCall::TruncF32 => wasmer_vm_f32_trunc as usize,
828 LibCall::TruncF64 => wasmer_vm_f64_trunc as usize,
829 LibCall::Memory32Size => wasmer_vm_memory32_size as usize,
830 LibCall::ImportedMemory32Size => wasmer_vm_imported_memory32_size as usize,
831 LibCall::TableCopy => wasmer_vm_table_copy as usize,
832 LibCall::TableInit => wasmer_vm_table_init as usize,
833 LibCall::TableFill => wasmer_vm_table_fill as usize,
834 LibCall::TableSize => wasmer_vm_table_size as usize,
835 LibCall::ImportedTableSize => wasmer_vm_imported_table_size as usize,
836 LibCall::TableGet => wasmer_vm_table_get as usize,
837 LibCall::ImportedTableGet => wasmer_vm_imported_table_get as usize,
838 LibCall::TableSet => wasmer_vm_table_set as usize,
839 LibCall::ImportedTableSet => wasmer_vm_imported_table_set as usize,
840 LibCall::TableGrow => wasmer_vm_table_grow as usize,
841 LibCall::ImportedTableGrow => wasmer_vm_imported_table_grow as usize,
842 LibCall::FuncRef => wasmer_vm_func_ref as usize,
843 LibCall::ElemDrop => wasmer_vm_elem_drop as usize,
844 LibCall::Memory32Copy => wasmer_vm_memory32_copy as usize,
845 LibCall::ImportedMemory32Copy => wasmer_vm_imported_memory32_copy as usize,
846 LibCall::Memory32Fill => wasmer_vm_memory32_fill as usize,
847 LibCall::ImportedMemory32Fill => wasmer_vm_imported_memory32_fill as usize,
848 LibCall::Memory32Init => wasmer_vm_memory32_init as usize,
849 LibCall::DataDrop => wasmer_vm_data_drop as usize,
850 LibCall::Probestack => wasmer_vm_probestack as usize,
851 LibCall::RaiseTrap => wasmer_vm_raise_trap as usize,
852 LibCall::Memory32AtomicWait32 => wasmer_vm_memory32_atomic_wait32 as usize,
853 LibCall::ImportedMemory32AtomicWait32 => wasmer_vm_imported_memory32_atomic_wait32 as usize,
854 LibCall::Memory32AtomicWait64 => wasmer_vm_memory32_atomic_wait64 as usize,
855 LibCall::ImportedMemory32AtomicWait64 => wasmer_vm_imported_memory32_atomic_wait64 as usize,
856 LibCall::Memory32AtomicNotify => wasmer_vm_memory32_atomic_notify as usize,
857 LibCall::ImportedMemory32AtomicNotify => wasmer_vm_imported_memory32_atomic_notify as usize,
858 }
859}