Class: Wasmtime::Instance

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

Overview

Represents a WebAssembly instance.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(store, mod, imports = []) ⇒ Instance

Parameters:

  • store (Store)

    The store to instantiate the module in.

  • mod (Module)

    The module to instantiate.

  • imports (Array<Func, Memory>) (defaults to: [])

    The module’s import, in orders that that they show up in the module.

Returns:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'ext/src/ruby_api/instance.rs', line 41

pub fn new(args: &[Value]) -> Result<Self, Error> {
    let args =
        scan_args::scan_args::<(Value, &Module), (Option<Value>,), (), (), (), ()>(args)?;
    let (s, module) = args.required;
    let wrapped_store: Obj<Store> = s.try_convert()?;
    let store = wrapped_store.get();
    let mut context = store.context_mut();
    let imports = args
        .optional
        .0
        .and_then(|v| if v.is_nil() { None } else { Some(v) });

    let imports: Vec<Extern> = match imports {
        Some(arr) => {
            let arr: RArray = arr.try_convert()?;
            let mut imports = Vec::with_capacity(arr.len());
            // SAFETY: arr won't get gc'd (it's on the stack) and we don't mutate it.
            for import in unsafe { arr.as_slice() } {
                context.data_mut().retain(*import);
                imports.push(import.to_extern()?);
            }
            imports
        }
        None => vec![],
    };

    let module = module.get();
    let inner = InstanceImpl::new(context, module, &imports)
        .map_err(|e| StoreContextValue::from(wrapped_store).handle_wasm_error(e))?;

    Ok(Self {
        inner,
        store: wrapped_store,
    })
}

Instance Method Details

#export(name) ⇒ Extern?

Get an export by name.

Parameters:

  • name (String)

Returns:

  • (Extern, nil)

    The export if it exists, nil otherwise.



114
115
116
117
118
119
120
121
122
123
# File 'ext/src/ruby_api/instance.rs', line 114

pub fn export(&self, str: RString) -> Result<Option<super::externals::Extern>, Error> {
    let store = self.store.get();
    let export = self
        .inner
        .get_export(store.context_mut(), unsafe { str.as_str()? });
    match export {
        Some(export) => export.wrap_wasmtime_type(self.store.into()).map(Some),
        None => Ok(None),
    }
}

#exportsHash{String => Extern}

Returns a Hash of exports where keys are export names as Strings and values are Externs.

Returns:



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'ext/src/ruby_api/instance.rs', line 91

pub fn exports(&self) -> Result<RHash, Error> {
    let store = self.store.get();
    let mut ctx = store.context_mut();
    let hash = RHash::new();

    for export in self.inner.exports(&mut ctx) {
        let export_name = RString::new(export.name());
        let wrapped_store = self.store;
        let wrapped_export = export
            .into_extern()
            .wrap_wasmtime_type(wrapped_store.into())?;
        hash.aset(export_name, wrapped_export)?;
    }

    Ok(hash)
}

#invoke(name, *args) ⇒ nil, ...

Retrieves a Wasm function from the instance and calls it. Essentially a shortcut for instance.export(name).call(…).

Parameters:

  • name (String)

    The name of function to run.

  • args (Object)

    The arguments to send to the Wasm function. Raises if the arguments do not conform to the Wasm function’s parameters.

Returns:

  • (nil, Object, Array<Object>)

    The return type depends on the function’s results arity:

    • 0 => nil

    • 1 => Object

    • > 1 => Array<Object>

See Also:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'ext/src/ruby_api/instance.rs', line 134

pub fn invoke(&self, args: &[Value]) -> Result<Value, Error> {
    let name: RString = args
        .get(0)
        .ok_or_else(|| {
            Error::new(
                magnus::exception::type_error(),
                "wrong number of arguments (given 0, expected 1+)",
            )
        })?
        .try_convert()?;

    let store: &Store = self.store.try_convert()?;
    let func = self.get_func(store.context_mut(), unsafe { name.as_str()? })?;
    Func::invoke(&self.store.into(), &func, &args[1..])
}