Class: Wasmtime::Memory
- Inherits:
-
Object
- Object
- Wasmtime::Memory
- Defined in:
- ext/src/ruby_api/memory.rs
Overview
Represents a WebAssembly memory.
Defined Under Namespace
Classes: UnsafeSlice
Class Method Summary collapse
Instance Method Summary collapse
-
#data_size ⇒ Integer
The number of bytes of the memory.
-
#grow(delta) ⇒ Integer
Grows a memory by
deltapages. -
#max_size ⇒ Integer?
The maximum number of memory pages.
-
#min_size ⇒ Integer
The minimum number of memory pages.
-
#read(offset, size) ⇒ String
Read
sizebytes starting atoffset. -
#read_cstring(offset) ⇒ String
Read a NUL-terminated C string starting at
offsetas an ASCII-8BIT (binary)String. -
#read_f32(offset) ⇒ Float
Read a little-endian
f32starting atoffset. -
#read_f64(offset) ⇒ Float
Read a little-endian
f64starting atoffset. -
#read_i32(offset) ⇒ Integer
Read a little-endian
i32starting atoffset. -
#read_i64(offset) ⇒ Integer
Read a little-endian
i64starting atoffset. -
#read_u32(offset) ⇒ Integer
Read a little-endian
u32starting atoffset. -
#read_u64(offset) ⇒ Integer
Read a little-endian
u64starting atoffset. -
#read_unsafe_slice(offset, size) ⇒ Wasmtime::Memory::UnsafeSlice
Read
sizebytes starting atoffsetinto an UnsafeSlice. -
#read_utf8(offset, size) ⇒ String
Read
sizebytes starting atoffset. -
#size ⇒ Integer
The number of pages of the memory.
-
#write(offset, value) ⇒ void
Write
valuestarting atoffset. -
#write_cstring(offset, value) ⇒ void
Write +value+'s bytes followed by a NUL terminator at
offset. -
#write_f32(offset, value) ⇒ void
Write a little-endian
f32starting atoffset. -
#write_f64(offset, value) ⇒ void
Write a little-endian
f64starting atoffset. -
#write_i32(offset, value) ⇒ void
Write a little-endian
i32starting atoffset. -
#write_i64(offset, value) ⇒ void
Write a little-endian
i64starting atoffset. -
#write_u32(offset, value) ⇒ void
Write a little-endian
u32starting atoffset. -
#write_u64(offset, value) ⇒ void
Write a little-endian
u64starting atoffset.
Class Method Details
.new(store, min_size:, max_size: nil) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'ext/src/ruby_api/memory.rs', line 84
pub fn new(args: &[Value]) -> Result<Self, Error> {
let args = scan_args::scan_args::<(Obj<Store>,), (), (), (), _, ()>(args)?;
let kw = scan_args::get_kwargs::<_, (u32,), (Option<u32>,), ()>(
args.keywords,
&[*MIN_SIZE],
&[*MAX_SIZE],
)?;
let (store,) = args.required;
let (min,) = kw.required;
let (max,) = kw.optional;
let memtype = wasmtime::MemoryType::new(min, max);
let inner = MemoryImpl::new(store.context_mut()?, memtype).map_err(|e| error!("{}", e))?;
Ok(Self {
store: store.into(),
inner,
})
}
|
Instance Method Details
#data_size ⇒ Integer
Returns The number of bytes of the memory.
418 419 420 |
# File 'ext/src/ruby_api/memory.rs', line 418
pub fn data_size(&self) -> Result<usize, Error> {
Ok(self.get_wasmtime_memory().data_size(self.store.context()?))
}
|
#grow(delta) ⇒ Integer
Grows a memory by delta pages.
Raises if the memory grows beyond its limit.
404 405 406 407 408 |
# File 'ext/src/ruby_api/memory.rs', line 404
pub fn grow(&self, delta: usize) -> Result<u64, Error> {
self.get_wasmtime_memory()
.grow(self.store.context_mut()?, delta as _)
.map_err(|e| error!("{}", e))
}
|
#max_size ⇒ Integer?
Returns The maximum number of memory pages.
120 121 122 123 124 125 |
# File 'ext/src/ruby_api/memory.rs', line 120
pub fn max_size(&self) -> Result<Option<u64>, Error> {
Ok(self
.get_wasmtime_memory()
.ty(self.store.context()?)
.maximum())
}
|
#min_size ⇒ Integer
Returns The minimum number of memory pages.
111 112 113 114 115 116 |
# File 'ext/src/ruby_api/memory.rs', line 111
pub fn min_size(&self) -> Result<u64, Error> {
Ok(self
.get_wasmtime_memory()
.ty(self.store.context()?)
.minimum())
}
|
#read(offset, size) ⇒ String
Read size bytes starting at offset. Result is a ASCII-8BIT encoded string.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'ext/src/ruby_api/memory.rs', line 134
pub fn read(
ruby: &Ruby,
rb_self: Obj<Self>,
offset: usize,
size: usize,
) -> Result<RString, Error> {
rb_self
.get_wasmtime_memory()
.data(rb_self.store.context()?)
.get(offset..)
.and_then(|s| s.get(..size))
.map(|s| ruby.str_from_slice(s))
.ok_or_else(|| error!("out of bounds memory access"))
}
|
#read_cstring(offset) ⇒ String
Read a NUL-terminated C string starting at offset as an ASCII-8BIT
(binary) String.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'ext/src/ruby_api/memory.rs', line 353
pub fn read_cstring(ruby: &Ruby, rb_self: Obj<Self>, offset: usize) -> Result<RString, Error> {
let context = rb_self.store.context()?;
let data = rb_self.get_wasmtime_memory().data(context);
let bytes: &[u8] = match data.get(offset..) {
Some(slice) => {
let end = slice.iter().position(|&b| b == 0).unwrap_or(slice.len());
&slice[..end]
}
None => &[],
};
Ok(ruby.str_from_slice(bytes))
}
|
#read_f32(offset) ⇒ Float
Read a little-endian f32 starting at offset.
266 267 268 |
# File 'ext/src/ruby_api/memory.rs', line 266
pub fn read_f32(&self, offset: usize) -> Result<f32, Error> {
Ok(f32::from_le_bytes(self.read_fixed::<4>(offset)?))
}
|
#read_f64(offset) ⇒ Float
Read a little-endian f64 starting at offset.
276 277 278 |
# File 'ext/src/ruby_api/memory.rs', line 276
pub fn read_f64(&self, offset: usize) -> Result<f64, Error> {
Ok(f64::from_le_bytes(self.read_fixed::<8>(offset)?))
}
|
#read_i32(offset) ⇒ Integer
Read a little-endian i32 starting at offset.
226 227 228 |
# File 'ext/src/ruby_api/memory.rs', line 226
pub fn read_i32(&self, offset: usize) -> Result<i32, Error> {
Ok(i32::from_le_bytes(self.read_fixed::<4>(offset)?))
}
|
#read_i64(offset) ⇒ Integer
Read a little-endian i64 starting at offset.
246 247 248 |
# File 'ext/src/ruby_api/memory.rs', line 246
pub fn read_i64(&self, offset: usize) -> Result<i64, Error> {
Ok(i64::from_le_bytes(self.read_fixed::<8>(offset)?))
}
|
#read_u32(offset) ⇒ Integer
Read a little-endian u32 starting at offset.
236 237 238 |
# File 'ext/src/ruby_api/memory.rs', line 236
pub fn read_u32(&self, offset: usize) -> Result<u32, Error> {
Ok(u32::from_le_bytes(self.read_fixed::<4>(offset)?))
}
|
#read_u64(offset) ⇒ Integer
Read a little-endian u64 starting at offset.
256 257 258 |
# File 'ext/src/ruby_api/memory.rs', line 256
pub fn read_u64(&self, offset: usize) -> Result<u64, Error> {
Ok(u64::from_le_bytes(self.read_fixed::<8>(offset)?))
}
|
#read_unsafe_slice(offset, size) ⇒ Wasmtime::Memory::UnsafeSlice
Read size bytes starting at offset into an UnsafeSlice. This
provides a way to read a slice of memory without copying the underlying
data.
The returned UnsafeSlice lazily reads the underlying memory, meaning that the actual pointer to the string buffer is not materialzed until Wasmtime::Memory::UnsafeSlice#to_str is called.
SAFETY: Resizing the memory (as with #grow) will
invalidate the UnsafeSlice, and future attempts to read the slice will raise
an error. However, it is not possible to invalidate the Ruby String
object after calling Wasmtime::Memory::UnsafeSlice#to_str. As such, the caller must ensure
that the Wasmtime Wasmtime::Memory is not resized while holding the Ruby string.
Failing to do so could result in the String buffer pointing to invalid
memory.
In general, you should prefer using #read or #read_utf8 over this method unless you know what you're doing.
196 197 198 199 200 201 202 203 |
# File 'ext/src/ruby_api/memory.rs', line 196
pub fn read_unsafe_slice(
ruby: &Ruby,
rb_self: Obj<Self>,
offset: usize,
size: usize,
) -> Result<Obj<UnsafeSlice<'a>>, Error> {
Ok(ruby.obj_wrap(UnsafeSlice::new(rb_self, offset..(offset + size))?))
}
|
#read_utf8(offset, size) ⇒ String
Read size bytes starting at offset. Result is a UTF-8 encoded string.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'ext/src/ruby_api/memory.rs', line 156
pub fn read_utf8(
ruby: &Ruby,
rb_self: Obj<Self>,
offset: usize,
size: usize,
) -> Result<RString, Error> {
rb_self
.get_wasmtime_memory()
.data(rb_self.store.context()?)
.get(offset..)
.and_then(|s| s.get(..size))
.ok_or_else(|| error!("out of bounds memory access"))
.and_then(|s| std::str::from_utf8(s).map_err(|e| error!("{}", e)))
.map(|s| ruby.str_new(s))
}
|
#size ⇒ Integer
Returns The number of pages of the memory.
412 413 414 |
# File 'ext/src/ruby_api/memory.rs', line 412
pub fn size(&self) -> Result<u64, Error> {
Ok(self.get_wasmtime_memory().size(self.store.context()?))
}
|
#write(offset, value) ⇒ void
This method returns an undefined value.
Write value starting at offset.
212 213 214 215 216 217 218 |
# File 'ext/src/ruby_api/memory.rs', line 212
pub fn write(&self, offset: usize, value: RString) -> Result<(), Error> {
let slice = unsafe { value.as_slice() };
self.get_wasmtime_memory()
.write(self.store.context_mut()?, offset, slice)
.map_err(|e| error!("{}", e))
}
|
#write_cstring(offset, value) ⇒ void
This method returns an undefined value.
Write +value+'s bytes followed by a NUL terminator at offset.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'ext/src/ruby_api/memory.rs', line 375
pub fn write_cstring(&self, offset: usize, value: RString) -> Result<(), Error> {
let slice = unsafe { value.as_slice() };
if slice.contains(&0) {
return Err(Error::new(
Ruby::get_with(value).exception_arg_error(),
"string contains null byte",
));
}
let len = slice.len();
let mut context = self.store.context_mut()?;
let dst = self
.get_wasmtime_memory()
.data_mut(&mut context)
.get_mut(offset..)
.and_then(|s| s.get_mut(..len + 1))
.ok_or_else(|| error!("out of bounds memory access"))?;
dst[..len].copy_from_slice(slice);
dst[len] = 0;
Ok(())
}
|
#write_f32(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian f32 starting at offset.
331 332 333 |
# File 'ext/src/ruby_api/memory.rs', line 331
pub fn write_f32(&self, offset: usize, value: f32) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|
#write_f64(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian f64 starting at offset.
342 343 344 |
# File 'ext/src/ruby_api/memory.rs', line 342
pub fn write_f64(&self, offset: usize, value: f64) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|
#write_i32(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian i32 starting at offset.
287 288 289 |
# File 'ext/src/ruby_api/memory.rs', line 287
pub fn write_i32(&self, offset: usize, value: i32) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|
#write_i64(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian i64 starting at offset.
309 310 311 |
# File 'ext/src/ruby_api/memory.rs', line 309
pub fn write_i64(&self, offset: usize, value: i64) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|
#write_u32(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian u32 starting at offset.
298 299 300 |
# File 'ext/src/ruby_api/memory.rs', line 298
pub fn write_u32(&self, offset: usize, value: u32) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|
#write_u64(offset, value) ⇒ void
This method returns an undefined value.
Write a little-endian u64 starting at offset.
320 321 322 |
# File 'ext/src/ruby_api/memory.rs', line 320
pub fn write_u64(&self, offset: usize, value: u64) -> Result<(), Error> {
self.write_fixed(offset, value.to_le_bytes())
}
|