Skip to content

Commit

Permalink
Add GlobalType (#349)
Browse files Browse the repository at this point in the history
* add GlobalType and Global::global_type getter

* clean up some GlobalType stuff

* add GlobalType::from_elements constructor

* add PartialEq and Eq derives for Mutability and GlobalType

* use crate::GlobalType in InstantiationError

* apply rustfmt
  • Loading branch information
Robbepop authored Jan 29, 2022
1 parent 022c751 commit 824e3e0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 38 deletions.
54 changes: 53 additions & 1 deletion wasmi_v1/src/global.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{AsContext, AsContextMut, Index, Stored};
use crate::{Value, ValueType};
use core::{fmt, fmt::Display};
use parity_wasm::elements as pwasm;

/// A raw index to a global variable entity.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
Expand Down Expand Up @@ -50,18 +51,59 @@ impl Display for GlobalError {
}

/// The mutability of a global variable.
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Mutability {
/// The value of the global variable is a constant.
Const,
/// The value of the global variable is mutable.
Mutable,
}

/// The type of a global variable.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct GlobalType {
/// The value type of the global variable.
value_type: ValueType,
/// The mutability of the global variable.
mutability: Mutability,
}

impl GlobalType {
pub fn new(value_type: ValueType, mutability: Mutability) -> Self {
Self {
value_type,
mutability,
}
}

/// Converts into [`GlobalType`] from [`pwasm::GlobalType`].
pub fn from_elements(global_type: pwasm::GlobalType) -> Self {
let value_type = ValueType::from_elements(global_type.content_type());
let mutability = if global_type.is_mutable() {
Mutability::Mutable
} else {
Mutability::Const
};
Self::new(value_type, mutability)
}

/// Returns the [`ValueType`] of the global variable.
pub fn value_type(&self) -> ValueType {
self.value_type
}

/// Returns the [`Mutability`] of the global variable.
pub fn mutability(&self) -> Mutability {
self.mutability
}
}

/// A global variable entitiy.
#[derive(Debug)]
pub struct GlobalEntity {
/// The current value of the global variable.
value: Value,
/// The mutability of the global variable.
mutability: Mutability,
}

Expand All @@ -84,6 +126,11 @@ impl GlobalEntity {
self.value.value_type()
}

/// Returns the [`GlobalType`] of the global variable.
pub fn global_type(&self) -> GlobalType {
GlobalType::new(self.value_type(), self.mutability)
}

/// Sets a new value to the global variable.
///
/// # Errors
Expand Down Expand Up @@ -157,6 +204,11 @@ impl Global {
ctx.as_context().store.resolve_global(*self).value_type()
}

/// Returns the [`GlobalType`] of the global variable.
pub fn global_type(&self, ctx: impl AsContext) -> GlobalType {
ctx.as_context().store.resolve_global(*self).global_type()
}

/// Sets a new value to the global variable.
///
/// # Errors
Expand Down
2 changes: 1 addition & 1 deletion wasmi_v1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub use self::{
external::Extern,
func::{Caller, Func, TypedFunc, WasmParams, WasmResults},
func_type::FuncType,
global::{Global, Mutability},
global::{Global, GlobalType, Mutability},
instance::{ExportsIter, Instance},
linker::Linker,
memory::{Memory, MemoryType},
Expand Down
47 changes: 11 additions & 36 deletions wasmi_v1/src/module/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use super::{
},
Module,
};
use crate::{Value, ValueType, F32, F64};
use crate::{GlobalType, Value, ValueType, F32, F64};
use core::{fmt, fmt::Display};
use parity_wasm::elements as pwasm;
use validation::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
Expand Down Expand Up @@ -62,17 +62,9 @@ pub enum InstantiationError {
/// Caused when a global variable has a mismatching global variable type and mutability.
GlobalTypeMismatch {
/// The expected global type for the global variable import.
///
/// # Note
///
/// The global type is required to match value type and mutability.
expected: pwasm::GlobalType,
/// The actual value type of the global variable import.
actual_type: ValueType,
/// The actual mutability of the global variable import.
///
/// This is `true` if the global variable is mutable.
actual_mutability: bool,
expected: GlobalType,
/// The actual global type found for the global variable import.
actual: GlobalType,
},
/// Caused when an element segment does not fit into the specified table instance.
ElementSegmentDoesNotFit {
Expand Down Expand Up @@ -112,20 +104,10 @@ impl Display for InstantiationError {
expected, actual
)
}
Self::GlobalTypeMismatch {
expected,
actual_type,
actual_mutability,
} => write!(
Self::GlobalTypeMismatch { expected, actual } => write!(
f,
"expected {:?} global type but found {} {:?} value type",
expected,
if *actual_mutability {
"mutable"
} else {
"immutable"
},
actual_type
"expected {:?} global type but found {:?} value type",
expected, actual,
),
Self::ElementSegmentDoesNotFit {
table,
Expand Down Expand Up @@ -396,17 +378,10 @@ impl Module {
builder.push_memory(memory);
}
(pwasm::External::Global(global_type), Extern::Global(global)) => {
let expected = *global_type;
let expected_type = ValueType::from_elements(expected.content_type());
let expected_mutability = expected.is_mutable();
let actual_type = global.value_type(context.as_context());
let actual_mutability = global.is_mutable(context.as_context());
if expected_type != actual_type || expected_mutability != actual_mutability {
return Err(InstantiationError::GlobalTypeMismatch {
expected,
actual_type,
actual_mutability,
});
let expected = GlobalType::from_elements(*global_type);
let actual = global.global_type(&context);
if expected != actual {
return Err(InstantiationError::GlobalTypeMismatch { expected, actual });
}
builder.push_global(global);
}
Expand Down

0 comments on commit 824e3e0

Please sign in to comment.