Skip to content

Commit

Permalink
Move Value from wasmi_core to wasmi crate (#636)
Browse files Browse the repository at this point in the history
* move Value from wasmi_core to wasmi

* fix doc link
  • Loading branch information
Robbepop committed Jan 25, 2023
1 parent 5f9d81a commit 90019d1
Show file tree
Hide file tree
Showing 19 changed files with 333 additions and 323 deletions.
3 changes: 2 additions & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use std::{
path::{Path, PathBuf},
};
use wasmi::{
core::{Value, ValueType, F32, F64},
core::{ValueType, F32, F64},
ExternType,
Func,
FuncType,
Store,
Value,
};

/// Simple program to greet a person
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ pub use self::{
trap::{Trap, TrapCode},
units::Pages,
untyped::{DecodeUntypedSlice, EncodeUntypedSlice, UntypedError, UntypedValue},
value::{TryFromValueError, Value, ValueType},
value::ValueType,
};
25 changes: 1 addition & 24 deletions crates/core/src/untyped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use crate::{
TrapCode,
TruncateSaturateInto,
TryTruncateInto,
Value,
ValueType,
WrapInto,
F32,
F64,
Expand All @@ -20,7 +18,7 @@ use core::{
};
use paste::paste;

/// An untyped [`Value`].
/// An untyped value.
///
/// Provides a dense and simple interface to all functional Wasm operations.
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
Expand All @@ -36,16 +34,6 @@ impl UntypedValue {
pub fn to_bits(self) -> u64 {
self.bits
}

/// Converts the [`UntypedValue`] into a [`Value`].
pub fn with_type(self, value_type: ValueType) -> Value {
match value_type {
ValueType::I32 => Value::I32(<_>::from(self)),
ValueType::I64 => Value::I64(<_>::from(self)),
ValueType::F32 => Value::F32(<_>::from(self)),
ValueType::F64 => Value::F64(<_>::from(self)),
}
}
}

macro_rules! impl_from_untyped_for_int {
Expand Down Expand Up @@ -80,17 +68,6 @@ impl From<UntypedValue> for bool {
}
}

impl From<Value> for UntypedValue {
fn from(value: Value) -> Self {
match value {
Value::I32(value) => value.into(),
Value::I64(value) => value.into(),
Value::F32(value) => value.into(),
Value::F64(value) => value.into(),
}
}
}

macro_rules! impl_from_unsigned_prim {
( $( $prim:ty ),* $(,)? ) => {
$(
Expand Down
265 changes: 0 additions & 265 deletions crates/core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,6 @@ impl Display for ValueType {
}
}

/// Runtime representation of a value.
///
/// Wasm code manipulate values of the four basic value types:
/// integers and floating-point (IEEE 754-2008) data of 32 or 64 bit width each, respectively.
///
/// There is no distinction between signed and unsigned integer types. Instead, integers are
/// interpreted by respective operations as either unsigned or signed in two’s complement representation.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Value {
/// Value of 32-bit signed or unsigned integer.
I32(i32),
/// Value of 64-bit signed or unsigned integer.
I64(i64),
/// Value of 32-bit IEEE 754-2008 floating point number.
F32(F32),
/// Value of 64-bit IEEE 754-2008 floating point number.
F64(F64),
}

impl Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::I32(value) => write!(f, "{value}"),
Self::I64(value) => write!(f, "{value}"),
Self::F32(value) => write!(f, "{}", f32::from(*value)),
Self::F64(value) => write!(f, "{}", f64::from(*value)),
}
}
}

/// Convert one type to another by wrapping.
pub trait WrapInto<T> {
/// Convert one type to another by wrapping.
Expand Down Expand Up @@ -242,241 +212,6 @@ pub trait Float<T>: ArithmeticOps<T> {
fn copysign(self, other: T) -> T;
}

impl Value {
/// Creates new default value of given type.
#[inline]
pub fn default(value_type: ValueType) -> Self {
match value_type {
ValueType::I32 => Value::I32(0),
ValueType::I64 => Value::I64(0),
ValueType::F32 => Value::F32(0f32.into()),
ValueType::F64 => Value::F64(0f64.into()),
}
}

/// Get variable type for this value.
#[inline]
pub fn ty(&self) -> ValueType {
match *self {
Value::I32(_) => ValueType::I32,
Value::I64(_) => ValueType::I64,
Value::F32(_) => ValueType::F32,
Value::F64(_) => ValueType::F64,
}
}

/// Returns `T` if this particular [`Value`] contains
/// appropriate type.
///
/// See [`FromValue`] for details.
///
/// [`FromValue`]: trait.FromValue.html
/// [`Value`]: enum.Value.html
#[inline]
pub fn try_into<T: TryFrom<Value>>(self) -> Option<T> {
<T as TryFrom<Value>>::try_from(self).ok()
}
}

impl From<i8> for Value {
#[inline]
fn from(val: i8) -> Self {
Value::I32(val.into())
}
}

impl From<i16> for Value {
#[inline]
fn from(val: i16) -> Self {
Value::I32(val.into())
}
}

impl From<i32> for Value {
#[inline]
fn from(val: i32) -> Self {
Value::I32(val)
}
}

impl From<i64> for Value {
#[inline]
fn from(val: i64) -> Self {
Value::I64(val)
}
}

impl From<u8> for Value {
#[inline]
fn from(val: u8) -> Self {
Value::I32(val.into())
}
}

impl From<u16> for Value {
#[inline]
fn from(val: u16) -> Self {
Value::I32(val.into())
}
}

impl From<u32> for Value {
#[inline]
fn from(val: u32) -> Self {
Value::I32(val.transmute_into())
}
}

impl From<u64> for Value {
#[inline]
fn from(val: u64) -> Self {
Value::I64(val.transmute_into())
}
}

impl From<F32> for Value {
#[inline]
fn from(val: F32) -> Self {
Value::F32(val)
}
}

impl From<F64> for Value {
#[inline]
fn from(val: F64) -> Self {
Value::F64(val)
}
}

macro_rules! impl_from_value {
($expected_rt_ty: ident, $into: ty) => {
impl TryFrom<Value> for $into {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::$expected_rt_ty(val) => Ok(val.transmute_into()),
_ => Err(Self::Error::TypeMismatch),
}
}
}
};
}

/// Errors that may occur upon converting a [`Value`] to a primitive type.
#[derive(Debug, Copy, Clone)]
pub enum TryFromValueError {
/// The type does not match the expected type.
TypeMismatch,
/// The value is out of bounds for the expected type.
OutOfBounds,
}

impl Display for TryFromValueError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TryFromValueError::TypeMismatch => write!(f, "encountered type mismatch"),
TryFromValueError::OutOfBounds => write!(f, "value out of bounds"),
}
}
}

/// This conversion assumes that boolean values are represented by
/// [`I32`] type.
///
/// [`I32`]: enum.Value.html#variant.I32
impl TryFrom<Value> for bool {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::I32(val) => Ok(val != 0),
_ => Err(Self::Error::TypeMismatch),
}
}
}

/// This conversion assumes that `i8` is represented as an [`I32`].
///
/// [`I32`]: enum.Value.html#variant.I32
impl TryFrom<Value> for i8 {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
let min = i32::from(i8::MIN);
let max = i32::from(i8::MAX);
match val {
Value::I32(val) if min <= val && val <= max => Ok(val as i8),
Value::I32(_) => Err(Self::Error::OutOfBounds),
_ => Err(Self::Error::TypeMismatch),
}
}
}

/// This conversion assumes that `i16` is represented as an [`I32`].
///
/// [`I32`]: enum.Value.html#variant.I32
impl TryFrom<Value> for i16 {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
let min = i32::from(i16::MIN);
let max = i32::from(i16::MAX);
match val {
Value::I32(val) if min <= val && val <= max => Ok(val as i16),
Value::I32(_) => Err(Self::Error::OutOfBounds),
_ => Err(Self::Error::TypeMismatch),
}
}
}

/// This conversion assumes that `u8` is represented as an [`I32`].
///
/// [`I32`]: enum.Value.html#variant.I32
impl TryFrom<Value> for u8 {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
let min = i32::from(u8::MIN);
let max = i32::from(u8::MAX);
match val {
Value::I32(val) if min <= val && val <= max => Ok(val as u8),
Value::I32(_) => Err(Self::Error::OutOfBounds),
_ => Err(Self::Error::TypeMismatch),
}
}
}

/// This conversion assumes that `u16` is represented as an [`I32`].
///
/// [`I32`]: enum.Value.html#variant.I32
impl TryFrom<Value> for u16 {
type Error = TryFromValueError;

#[inline]
fn try_from(val: Value) -> Result<Self, Self::Error> {
let min = i32::from(u16::MIN);
let max = i32::from(u16::MAX);
match val {
Value::I32(val) if min <= val && val <= max => Ok(val as u16),
Value::I32(_) => Err(Self::Error::OutOfBounds),
_ => Err(Self::Error::TypeMismatch),
}
}
}

impl_from_value!(I32, i32);
impl_from_value!(I64, i64);
impl_from_value!(F32, F32);
impl_from_value!(F64, F64);
impl_from_value!(I32, u32);
impl_from_value!(I64, u64);

macro_rules! impl_wrap_into {
($from:ident, $into:ident) => {
impl WrapInto<$into> for $from {
Expand Down
11 changes: 1 addition & 10 deletions crates/wasmi/benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,7 @@ use self::bench::{
};
use criterion::{criterion_group, criterion_main, Bencher, Criterion};
use std::{slice, time::Duration};
use wasmi::{
core::{TrapCode, Value},
Engine,
Extern,
Func,
Linker,
Memory,
Module,
Store,
};
use wasmi::{core::TrapCode, Engine, Extern, Func, Linker, Memory, Module, Store, Value};
use wasmi_core::{Pages, ValueType, F32, F64};

criterion_group!(
Expand Down
3 changes: 2 additions & 1 deletion crates/wasmi/src/engine/func_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ use crate::{
Engine,
FuncType,
Mutability,
Value,
};
use alloc::vec::Vec;
use wasmi_core::{Value, ValueType, F32, F64};
use wasmi_core::{ValueType, F32, F64};

/// The used function validator type.
type FuncValidator = wasmparser::FuncValidator<wasmparser::ValidatorResources>;
Expand Down
Loading

0 comments on commit 90019d1

Please sign in to comment.