Read the value at the given offset. # Safety The `offset` and `ty` must correspond to a valid value written to the frame by generated code of the correct type. This will be the case if this information comes from the frame tables (as long as the frontend that generates the tables and instrumentation is correct, and as long as the tables are preserved through serialization).
(
store: &mut StoreOpaque,
slot_base: *const u8,
offset: FrameStateSlotOffset,
ty: FrameValType,
)
| 765 | /// instrumentation is correct, and as long as the tables are |
| 766 | /// preserved through serialization). |
| 767 | unsafe fn read_value( |
| 768 | store: &mut StoreOpaque, |
| 769 | slot_base: *const u8, |
| 770 | offset: FrameStateSlotOffset, |
| 771 | ty: FrameValType, |
| 772 | ) -> Val { |
| 773 | let address = unsafe { slot_base.offset(isize::try_from(offset.offset()).unwrap()) }; |
| 774 | |
| 775 | // SAFETY: each case reads a value from memory that should be |
| 776 | // valid according to our safety condition. |
| 777 | match ty { |
| 778 | FrameValType::I32 => { |
| 779 | let value = unsafe { *(address as *const i32) }; |
| 780 | Val::I32(value) |
| 781 | } |
| 782 | FrameValType::I64 => { |
| 783 | let value = unsafe { *(address as *const i64) }; |
| 784 | Val::I64(value) |
| 785 | } |
| 786 | FrameValType::F32 => { |
| 787 | let value = unsafe { *(address as *const u32) }; |
| 788 | Val::F32(value) |
| 789 | } |
| 790 | FrameValType::F64 => { |
| 791 | let value = unsafe { *(address as *const u64) }; |
| 792 | Val::F64(value) |
| 793 | } |
| 794 | FrameValType::V128 => { |
| 795 | // Vectors are always stored as little-endian. |
| 796 | let value = unsafe { u128::from_le_bytes(*(address as *const [u8; 16])) }; |
| 797 | Val::V128(value.into()) |
| 798 | } |
| 799 | FrameValType::AnyRef => { |
| 800 | let mut nogc = AutoAssertNoGc::new(store); |
| 801 | let value = unsafe { *(address as *const u32) }; |
| 802 | let value = AnyRef::_from_raw(&mut nogc, value); |
| 803 | Val::AnyRef(value) |
| 804 | } |
| 805 | FrameValType::ExnRef => { |
| 806 | let mut nogc = AutoAssertNoGc::new(store); |
| 807 | let value = unsafe { *(address as *const u32) }; |
| 808 | let value = ExnRef::_from_raw(&mut nogc, value); |
| 809 | Val::ExnRef(value) |
| 810 | } |
| 811 | FrameValType::ExternRef => { |
| 812 | let mut nogc = AutoAssertNoGc::new(store); |
| 813 | let value = unsafe { *(address as *const u32) }; |
| 814 | let value = ExternRef::_from_raw(&mut nogc, value); |
| 815 | Val::ExternRef(value) |
| 816 | } |
| 817 | FrameValType::FuncRef => { |
| 818 | let value = unsafe { *(address as *const *mut c_void) }; |
| 819 | let value = unsafe { Func::_from_raw(store, value) }; |
| 820 | Val::FuncRef(value) |
| 821 | } |
| 822 | FrameValType::ContRef => { |
| 823 | unimplemented!("contref values are not implemented in the host API yet") |
| 824 | } |