///|
/// Runtime representation of a global variable
struct GlobalInstance {
mut binding : ResourceBinding?
type_ : @types.GlobalType
mut value : @types.Value
mut native : NativeGlobalBinding?
} derive(Debug)
///|
pub fn GlobalInstance::GlobalInstance(
type_ : @types.GlobalType,
value : @types.Value,
) -> GlobalInstance raise RuntimeError {
guard value_fits_kind(value, type_.value_type) else { raise TypeMismatch }
{ type_, value, native: None, binding: None, }
}
///|
pub fn GlobalInstance::get(
self : GlobalInstance,
) -> @types.Value raise RuntimeError {
check_resource_open(self.binding)
match self.native {
Some(binding) => (binding.read)()
None => self.value
}
}
///|
pub fn GlobalInstance::set(
self : GlobalInstance,
value : @types.Value,
) -> Unit raise RuntimeError {
check_resource_open(self.binding)
guard value_fits_kind(value, self.type_.value_type) else {
raise TypeMismatch
}
if !self.type_.mutable {
raise TypeMismatch // attempting to mutate immutable global
}
match self.native {
Some(binding) => (binding.write)(value)
None => self.value = value
}
}
///|
/// Get global type for type checking
pub fn GlobalInstance::get_type(self : GlobalInstance) -> @types.GlobalType {
self.type_
}
///|
/// Shared native storage for one store global, independent of module indices.
pub(all) struct NativeGlobalBinding {
address : Int64
root : () -> @types.Value
read : () -> @types.Value raise RuntimeError
write : (@types.Value) -> Unit raise RuntimeError
release : () -> Unit
}
///|
pub impl Debug for NativeGlobalBinding with fn to_repr(_self) {
Repr::literal("NativeGlobalBinding")
}
///|
pub fn GlobalInstance::native_binding(
self : GlobalInstance,
) -> NativeGlobalBinding? {
self.native
}
///|
pub fn GlobalInstance::bind_native(
self : GlobalInstance,
binding : NativeGlobalBinding,
) -> Unit {
self.native = Some(binding)
}
///|
fn GlobalInstance::close(self : GlobalInstance) -> Unit {
if self.binding is Some(binding) {
binding.active.val = false
}
self.value = Null
if self.native is Some(binding) {
self.native = None
(binding.release)()
}
}
///|
fn GlobalInstance::root(self : GlobalInstance) -> @types.Value {
match self.native {
Some(binding) => (binding.root)()
None => self.value
}
}
///|
pub extend NativeGlobalBinding with Debug::{to_repr}