Update behavior of zero-length lists/strings (#4648)

The spec was expected to change to not bounds-check 0-byte lists/strings
but has since been updated to match `memory.copy` which does indeed
check the pointer for 0-byte copies.
This commit is contained in:
Alex Crichton
2022-08-09 09:26:33 -05:00
committed by GitHub
parent 8aee85ebaa
commit 867f5c1244
5 changed files with 89 additions and 184 deletions

View File

@@ -1,5 +1,6 @@
use crate::store::{StoreId, StoreOpaque};
use crate::StoreContextMut;
use crate::Trap;
use anyhow::{bail, Result};
use std::ptr::NonNull;
use wasmtime_environ::component::StringEncoding;
@@ -96,19 +97,15 @@ impl Options {
};
if result % old_align != 0 {
bail!("realloc return: result not aligned");
bail!(Trap::new("realloc return: result not aligned"));
}
let result = usize::try_from(result)?;
let memory = self.memory_mut(store.0);
let result_slice = if new_size == 0 {
&mut []
} else {
match memory.get_mut(result..).and_then(|s| s.get_mut(..new_size)) {
Some(end) => end,
None => bail!("realloc return: beyond end of memory"),
}
let result_slice = match memory.get_mut(result..).and_then(|s| s.get_mut(..new_size)) {
Some(end) => end,
None => bail!(Trap::new("realloc return: beyond end of memory")),
};
Ok((result_slice, result))

View File

@@ -875,9 +875,7 @@ fn lower_string<T>(mem: &mut MemoryMut<'_, T>, string: &str) -> Result<(usize, u
);
}
let ptr = mem.realloc(0, 0, 1, string.len())?;
if string.len() > 0 {
mem.as_slice_mut()[ptr..][..string.len()].copy_from_slice(string.as_bytes());
}
mem.as_slice_mut()[ptr..][..string.len()].copy_from_slice(string.as_bytes());
Ok((ptr, string.len()))
}
@@ -894,17 +892,15 @@ fn lower_string<T>(mem: &mut MemoryMut<'_, T>, string: &str) -> Result<(usize, u
}
let mut ptr = mem.realloc(0, 0, 2, size)?;
let mut copied = 0;
if size > 0 {
let bytes = &mut mem.as_slice_mut()[ptr..][..size];
for (u, bytes) in string.encode_utf16().zip(bytes.chunks_mut(2)) {
let u_bytes = u.to_le_bytes();
bytes[0] = u_bytes[0];
bytes[1] = u_bytes[1];
copied += 1;
}
if (copied * 2) < size {
ptr = mem.realloc(ptr, size, 2, copied * 2)?;
}
let bytes = &mut mem.as_slice_mut()[ptr..][..size];
for (u, bytes) in string.encode_utf16().zip(bytes.chunks_mut(2)) {
let u_bytes = u.to_le_bytes();
bytes[0] = u_bytes[0];
bytes[1] = u_bytes[1];
copied += 1;
}
if (copied * 2) < size {
ptr = mem.realloc(ptr, size, 2, copied * 2)?;
}
Ok((ptr, copied))
}