Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use bytes for reading Region from wasm memory #2005

Merged
merged 4 commits into from
Jan 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions packages/vm/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::mem::MaybeUninit;
use std::mem::{size_of, MaybeUninit};

use wasmer::{ValueType, WasmPtr};

Expand All @@ -25,6 +25,35 @@ pub struct Region {
/// The number of bytes used in this region
pub length: u32,
}
type RegionBytes = [u8; size_of::<Region>()];

chipshort marked this conversation as resolved.
Show resolved Hide resolved
impl Region {
fn from_wasm_bytes(bytes: RegionBytes) -> Self {
let offset = u32::from_le_bytes(bytes[0..4].try_into().unwrap());
let capacity = u32::from_le_bytes(bytes[4..8].try_into().unwrap());
chipshort marked this conversation as resolved.
Show resolved Hide resolved
let length = u32::from_le_bytes(bytes[8..12].try_into().unwrap());
Region {
offset,
capacity,
length,
}
}

fn into_wasm_bytes(self) -> RegionBytes {
let Region {
offset,
capacity,
length,
} = self;

let mut bytes = [0u8; 12];
// wasm is little endian
bytes[0..4].copy_from_slice(&offset.to_le_bytes());
bytes[4..8].copy_from_slice(&capacity.to_le_bytes());
bytes[8..12].copy_from_slice(&length.to_le_bytes());
bytes
}
}

unsafe impl ValueType for Region {
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {
Expand Down Expand Up @@ -91,10 +120,10 @@ pub fn write_region(memory: &wasmer::MemoryView, ptr: u32, data: &[u8]) -> VmRes

/// Reads in a Region at offset in Wasm memory and returns a copy of it
fn get_region(memory: &wasmer::MemoryView, offset: u32) -> CommunicationResult<Region> {
let wptr = WasmPtr::<Region>::new(offset);
let region = wptr.deref(memory).read().map_err(|_err| {
let wptr = WasmPtr::<RegionBytes>::new(offset);
let region = Region::from_wasm_bytes(wptr.deref(memory).read().map_err(|_err| {
CommunicationError::deref_err(offset, "Could not dereference this pointer to a Region")
})?;
})?);
validate_region(&region)?;
Ok(region)
}
Expand Down Expand Up @@ -122,10 +151,12 @@ fn validate_region(region: &Region) -> RegionValidationResult<()> {

/// Overrides a Region at offset in Wasm memory
fn set_region(memory: &wasmer::MemoryView, offset: u32, data: Region) -> CommunicationResult<()> {
let wptr = WasmPtr::<Region>::new(offset);
wptr.deref(memory).write(data).map_err(|_err| {
CommunicationError::deref_err(offset, "Could not dereference this pointer to a Region")
})?;
let wptr = WasmPtr::<RegionBytes>::new(offset);
wptr.deref(memory)
.write(data.into_wasm_bytes())
.map_err(|_err| {
CommunicationError::deref_err(offset, "Could not dereference this pointer to a Region")
})?;
Ok(())
}

Expand Down
Loading