Class: Wasmtime::Memory

Inherits:
Object
  • Object
show all
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

Class Method Details

.new(store, min_size:, max_size: nil) ⇒ Object

Parameters:

  • store (Store)
  • min_size (Integer)

    The minimum memory pages.

  • max_size (Integer, nil) (defaults to: nil)

    The maximum memory pages.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'ext/src/ruby_api/memory.rs', line 87

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))?;
    let memsize = inner.data_size(store.context_mut());

    Ok(Self {
        store: store.into(),
        inner: ManuallyTracked::wrap(inner, memsize),
    })
}

Instance Method Details

#data_sizeInteger

Returns The number of bytes of the memory.

Returns:

  • (Integer)

    The number of bytes of the memory.



246
247
248
# File 'ext/src/ruby_api/memory.rs', line 246

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.

Parameters:

  • delta (Integer)

    The number of pages to grow by.

Returns:

  • (Integer)

    The number of pages the memory had before being resized.



226
227
228
229
230
231
232
233
234
235
236
# File 'ext/src/ruby_api/memory.rs', line 226

pub fn grow(&self, delta: usize) -> Result<u64, Error> {
    let ret = self
        .get_wasmtime_memory()
        .grow(self.store.context_mut()?, delta as _)
        .map_err(|e| error!("{}", e));

    self.inner
        .increase_memory_usage(delta * (WASM_PAGE_SIZE as usize));

    ret
}

#max_sizeInteger?

Returns The maximum number of memory pages.

Returns:

  • (Integer, nil)

    The maximum number of memory pages.



129
130
131
132
133
134
# File 'ext/src/ruby_api/memory.rs', line 129

pub fn max_size(&self) -> Result<Option<u64>, Error> {
    Ok(self
        .get_wasmtime_memory()
        .ty(self.store.context()?)
        .maximum())
}

#min_sizeInteger

Returns The minimum number of memory pages.

Returns:

  • (Integer)

    The minimum number of memory pages.



120
121
122
123
124
125
# File 'ext/src/ruby_api/memory.rs', line 120

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.

Parameters:

  • offset (Integer)
  • size (Integer)

Returns:

  • (String)

    Binary String of the memory.



143
144
145
146
147
148
149
150
# File 'ext/src/ruby_api/memory.rs', line 143

pub fn read(&self, offset: usize, size: usize) -> Result<RString, Error> {
    self.get_wasmtime_memory()
        .data(self.store.context()?)
        .get(offset..)
        .and_then(|s| s.get(..size))
        .map(RString::from_slice)
        .ok_or_else(|| error!("out of bounds memory access"))
}

#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.

Parameters:

  • offset (Integer)
  • size (Integer)

Returns:



193
194
195
196
197
198
199
200
201
202
# File 'ext/src/ruby_api/memory.rs', line 193

pub fn read_unsafe_slice(
    rb_self: Obj<Self>,
    offset: usize,
    size: usize,
) -> Result<Obj<UnsafeSlice<'a>>, Error> {
    Ok(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.

Parameters:

  • offset (Integer)
  • size (Integer)

Returns:

  • (String)

    UTF-8 String of the memory.



159
160
161
162
163
164
165
166
167
# File 'ext/src/ruby_api/memory.rs', line 159

pub fn read_utf8(&self, offset: usize, size: usize) -> Result<RString, Error> {
    self.get_wasmtime_memory()
        .data(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(RString::new)
}

#sizeInteger

Returns The number of pages of the memory.

Returns:

  • (Integer)

    The number of pages of the memory.



240
241
242
# File 'ext/src/ruby_api/memory.rs', line 240

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.

Parameters:

  • offset (Integer)
  • value (String)


211
212
213
214
215
216
217
# File 'ext/src/ruby_api/memory.rs', line 211

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))
}