Class: Wasmtime::Memory

Inherits:
Object
  • Object
show all
Defined in:
ext/src/ruby_api/memory.rs

Overview

Represents a WebAssembly memory.

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.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'ext/src/ruby_api/memory.rs', line 60

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 (s,) = args.required;
    let (min,) = kw.required;
    let (max,) = kw.optional;
    let store = s.get();

    let memtype = wasmtime::MemoryType::new(min, max);
    let inner = MemoryImpl::new(store.context_mut(), memtype).map_err(|e| error!("{}", e))?;

    Ok(Self {
        store: s.into(),
        inner,
    })
}

Instance Method Details

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



187
188
189
190
191
# File 'ext/src/ruby_api/memory.rs', line 187

pub fn grow(&self, delta: u64) -> Result<u64, Error> {
    self.inner
        .grow(self.store.context_mut()?, delta)
        .map_err(|e| error!("{}", e))
}

#max_sizeInteger?

Returns The maximum number of memory pages.

Returns:

  • (Integer, nil)

    The maximum number of memory pages.



93
94
95
# File 'ext/src/ruby_api/memory.rs', line 93

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

#min_sizeInteger

Returns The minimum number of memory pages.

Returns:

  • (Integer)

    The minimum number of memory pages.



87
88
89
# File 'ext/src/ruby_api/memory.rs', line 87

pub fn min_size(&self) -> Result<u64, Error> {
    Ok(self.inner.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.



104
105
106
107
108
109
110
111
# File 'ext/src/ruby_api/memory.rs', line 104

pub fn read(&self, offset: usize, size: usize) -> Result<RString, Error> {
    self.inner
        .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:



154
155
156
157
158
159
160
161
162
163
# File 'ext/src/ruby_api/memory.rs', line 154

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.



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

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



195
196
197
# File 'ext/src/ruby_api/memory.rs', line 195

pub fn size(&self) -> Result<u64, Error> {
    Ok(self.inner.size(self.store.context()?))
}

#write(offset, value) ⇒ void

This method returns an undefined value.

Write value starting at offset.

Parameters:

  • offset (Integer)
  • value (String)


172
173
174
175
176
177
178
# File 'ext/src/ruby_api/memory.rs', line 172

pub fn write(&self, offset: usize, value: RString) -> Result<(), Error> {
    let slice = unsafe { value.as_slice() };

    self.inner
        .write(self.store.context_mut()?, offset, slice)
        .map_err(|e| error!("{}", e))
}