Struct wasmtime::GlobalType
source · pub struct GlobalType { /* private fields */ }Expand description
A WebAssembly global descriptor.
This type describes an instance of a global in a WebAssembly module. Globals
are local to an Instance and are either immutable or
mutable.
Implementations§
source§impl GlobalType
impl GlobalType
sourcepub fn new(content: ValType, mutability: Mutability) -> GlobalType
pub fn new(content: ValType, mutability: Mutability) -> GlobalType
Creates a new global descriptor of the specified content type and
whether or not it’s mutable.
sourcepub fn content(&self) -> &ValType
pub fn content(&self) -> &ValType
Returns the value type of this global descriptor.
Examples found in repository?
src/externals.rs (line 252)
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
fn _new(store: &mut StoreOpaque, ty: GlobalType, val: Val) -> Result<Global> {
if !val.comes_from_same_store(store) {
bail!("cross-`Store` globals are not supported");
}
if val.ty() != *ty.content() {
bail!("value provided does not match the type of this global");
}
unsafe {
let wasmtime_export = generate_global_export(store, &ty, val)?;
Ok(Global::from_wasmtime_global(wasmtime_export, store))
}
}
/// Returns the underlying type of this `global`.
///
/// # Panics
///
/// Panics if `store` does not own this global.
pub fn ty(&self, store: impl AsContext) -> GlobalType {
let store = store.as_context();
let ty = &store[self.0].global;
GlobalType::from_wasmtime_global(&ty)
}
/// Returns the current [`Val`] of this global.
///
/// # Panics
///
/// Panics if `store` does not own this global.
pub fn get(&self, mut store: impl AsContextMut) -> Val {
unsafe {
let store = store.as_context_mut();
let definition = &*store[self.0].definition;
match self.ty(&store).content() {
ValType::I32 => Val::from(*definition.as_i32()),
ValType::I64 => Val::from(*definition.as_i64()),
ValType::F32 => Val::F32(*definition.as_u32()),
ValType::F64 => Val::F64(*definition.as_u64()),
ValType::ExternRef => Val::ExternRef(
definition
.as_externref()
.clone()
.map(|inner| ExternRef { inner }),
),
ValType::FuncRef => {
Val::FuncRef(Func::from_raw(store, definition.as_anyfunc() as usize))
}
ValType::V128 => Val::V128(*definition.as_u128()),
}
}
}
/// Attempts to set the current value of this global to [`Val`].
///
/// # Errors
///
/// Returns an error if this global has a different type than `Val`, if
/// it's not a mutable global, or if `val` comes from a different store than
/// the one provided.
///
/// # Panics
///
/// Panics if `store` does not own this global.
pub fn set(&self, mut store: impl AsContextMut, val: Val) -> Result<()> {
let store = store.as_context_mut().0;
let ty = self.ty(&store);
if ty.mutability() != Mutability::Var {
bail!("immutable global cannot be set");
}
let ty = ty.content();
if val.ty() != *ty {
bail!("global of type {:?} cannot be set to {:?}", ty, val.ty());
}
if !val.comes_from_same_store(store) {
bail!("cross-`Store` values are not supported");
}
unsafe {
let definition = &mut *store[self.0].definition;
match val {
Val::I32(i) => *definition.as_i32_mut() = i,
Val::I64(i) => *definition.as_i64_mut() = i,
Val::F32(f) => *definition.as_u32_mut() = f,
Val::F64(f) => *definition.as_u64_mut() = f,
Val::FuncRef(f) => {
*definition.as_anyfunc_mut() = f.map_or(ptr::null(), |f| {
f.caller_checked_anyfunc(store).as_ptr().cast()
});
}
Val::ExternRef(x) => {
let old = mem::replace(definition.as_externref_mut(), x.map(|x| x.inner));
drop(old);
}
Val::V128(i) => *definition.as_u128_mut() = i,
}
}
Ok(())
}More examples
src/trampoline/global.rs (line 17)
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 76 77 78 79 80 81
pub fn create_global(store: &mut StoreOpaque, gt: &GlobalType, val: Val) -> Result<InstanceId> {
let mut module = Module::new();
let mut func_imports = Vec::new();
let mut externref_init = None;
let mut one_signature = None;
let global = Global {
wasm_ty: gt.content().to_wasm_type(),
mutability: match gt.mutability() {
Mutability::Const => false,
Mutability::Var => true,
},
initializer: match val {
Val::I32(i) => GlobalInit::I32Const(i),
Val::I64(i) => GlobalInit::I64Const(i),
Val::F32(f) => GlobalInit::F32Const(f),
Val::F64(f) => GlobalInit::F64Const(f),
Val::V128(i) => GlobalInit::V128Const(i.into()),
Val::ExternRef(None) | Val::FuncRef(None) => GlobalInit::RefNullConst,
Val::ExternRef(Some(x)) => {
// There is no `GlobalInit` variant for using an existing
// `externref` that isn't an import (because Wasm can't create
// an `externref` by itself). Therefore, initialize the global
// as null, and then monkey patch it after instantiation below.
externref_init = Some(x);
GlobalInit::RefNullConst
}
Val::FuncRef(Some(f)) => {
// Add a function import to the stub module, and then initialize
// our global with a `ref.func` to grab that imported function.
let f = f.caller_checked_anyfunc(store);
let f = unsafe { f.as_ref() };
let sig_id = SignatureIndex::from_u32(0);
one_signature = Some(f.type_index);
module.types.push(ModuleType::Function(sig_id));
let func_index = module.push_escaped_function(sig_id, AnyfuncIndex::from_u32(0));
module.num_imported_funcs = 1;
module.num_escaped_funcs = 1;
module
.initializers
.push(wasmtime_environ::Initializer::Import {
name: "".into(),
field: "".into(),
index: EntityIndex::Function(func_index),
});
func_imports.push(VMFunctionImport {
body: f.func_ptr,
vmctx: f.vmctx,
});
GlobalInit::RefFunc(func_index)
}
},
};
let global_id = module.globals.push(global);
module
.exports
.insert(String::new(), EntityIndex::Global(global_id));
let id = create_handle(module, store, Box::new(()), &func_imports, one_signature)?;
if let Some(x) = externref_init {
let instance = store.instance_mut(id);
let g = instance.get_exported_global(global_id);
unsafe {
*(*g.definition).as_externref_mut() = Some(x.inner);
}
}
Ok(id)
}sourcepub fn mutability(&self) -> Mutability
pub fn mutability(&self) -> Mutability
Returns whether or not this global is mutable.
Examples found in repository?
src/externals.rs (line 314)
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
pub fn set(&self, mut store: impl AsContextMut, val: Val) -> Result<()> {
let store = store.as_context_mut().0;
let ty = self.ty(&store);
if ty.mutability() != Mutability::Var {
bail!("immutable global cannot be set");
}
let ty = ty.content();
if val.ty() != *ty {
bail!("global of type {:?} cannot be set to {:?}", ty, val.ty());
}
if !val.comes_from_same_store(store) {
bail!("cross-`Store` values are not supported");
}
unsafe {
let definition = &mut *store[self.0].definition;
match val {
Val::I32(i) => *definition.as_i32_mut() = i,
Val::I64(i) => *definition.as_i64_mut() = i,
Val::F32(f) => *definition.as_u32_mut() = f,
Val::F64(f) => *definition.as_u64_mut() = f,
Val::FuncRef(f) => {
*definition.as_anyfunc_mut() = f.map_or(ptr::null(), |f| {
f.caller_checked_anyfunc(store).as_ptr().cast()
});
}
Val::ExternRef(x) => {
let old = mem::replace(definition.as_externref_mut(), x.map(|x| x.inner));
drop(old);
}
Val::V128(i) => *definition.as_u128_mut() = i,
}
}
Ok(())
}More examples
src/trampoline/global.rs (line 18)
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 76 77 78 79 80 81
pub fn create_global(store: &mut StoreOpaque, gt: &GlobalType, val: Val) -> Result<InstanceId> {
let mut module = Module::new();
let mut func_imports = Vec::new();
let mut externref_init = None;
let mut one_signature = None;
let global = Global {
wasm_ty: gt.content().to_wasm_type(),
mutability: match gt.mutability() {
Mutability::Const => false,
Mutability::Var => true,
},
initializer: match val {
Val::I32(i) => GlobalInit::I32Const(i),
Val::I64(i) => GlobalInit::I64Const(i),
Val::F32(f) => GlobalInit::F32Const(f),
Val::F64(f) => GlobalInit::F64Const(f),
Val::V128(i) => GlobalInit::V128Const(i.into()),
Val::ExternRef(None) | Val::FuncRef(None) => GlobalInit::RefNullConst,
Val::ExternRef(Some(x)) => {
// There is no `GlobalInit` variant for using an existing
// `externref` that isn't an import (because Wasm can't create
// an `externref` by itself). Therefore, initialize the global
// as null, and then monkey patch it after instantiation below.
externref_init = Some(x);
GlobalInit::RefNullConst
}
Val::FuncRef(Some(f)) => {
// Add a function import to the stub module, and then initialize
// our global with a `ref.func` to grab that imported function.
let f = f.caller_checked_anyfunc(store);
let f = unsafe { f.as_ref() };
let sig_id = SignatureIndex::from_u32(0);
one_signature = Some(f.type_index);
module.types.push(ModuleType::Function(sig_id));
let func_index = module.push_escaped_function(sig_id, AnyfuncIndex::from_u32(0));
module.num_imported_funcs = 1;
module.num_escaped_funcs = 1;
module
.initializers
.push(wasmtime_environ::Initializer::Import {
name: "".into(),
field: "".into(),
index: EntityIndex::Function(func_index),
});
func_imports.push(VMFunctionImport {
body: f.func_ptr,
vmctx: f.vmctx,
});
GlobalInit::RefFunc(func_index)
}
},
};
let global_id = module.globals.push(global);
module
.exports
.insert(String::new(), EntityIndex::Global(global_id));
let id = create_handle(module, store, Box::new(()), &func_imports, one_signature)?;
if let Some(x) = externref_init {
let instance = store.instance_mut(id);
let g = instance.get_exported_global(global_id);
unsafe {
*(*g.definition).as_externref_mut() = Some(x.inner);
}
}
Ok(id)
}Trait Implementations§
source§impl Clone for GlobalType
impl Clone for GlobalType
source§fn clone(&self) -> GlobalType
fn clone(&self) -> GlobalType
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moresource§impl Debug for GlobalType
impl Debug for GlobalType
source§impl From<GlobalType> for ExternType
impl From<GlobalType> for ExternType
source§fn from(ty: GlobalType) -> ExternType
fn from(ty: GlobalType) -> ExternType
Converts to this type from the input type.
source§impl Hash for GlobalType
impl Hash for GlobalType
source§impl PartialEq<GlobalType> for GlobalType
impl PartialEq<GlobalType> for GlobalType
source§fn eq(&self, other: &GlobalType) -> bool
fn eq(&self, other: &GlobalType) -> bool
This method tests for
self and other values to be equal, and is used
by ==.impl Eq for GlobalType
impl StructuralEq for GlobalType
impl StructuralPartialEq for GlobalType
Auto Trait Implementations§
impl RefUnwindSafe for GlobalType
impl Send for GlobalType
impl Sync for GlobalType
impl Unpin for GlobalType
impl UnwindSafe for GlobalType
Blanket Implementations§
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key and return true if they are equal.