mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 04:28:01 +00:00
Add get_global for Sandbox (#4756)
* Add `get_global` for `Sandbox` This pr adds `get_global` to retrieve a `global` variable from an instantiated sandbox wasm blob. * Bump `spec_version` * Update primitives/wasm-interface/src/lib.rs Co-Authored-By: Sergei Pepyakin <sergei@parity.io> * `get_global` -> `get_global_val` Co-authored-by: Sergei Pepyakin <s.pepyakin@gmail.com> Co-authored-by: Gavin Wood <github@gavwood.com>
This commit is contained in:
@@ -44,8 +44,33 @@ pub enum ValueType {
|
||||
F64,
|
||||
}
|
||||
|
||||
impl From<ValueType> for u8 {
|
||||
fn from(val: ValueType) -> u8 {
|
||||
match val {
|
||||
ValueType::I32 => 0,
|
||||
ValueType::I64 => 1,
|
||||
ValueType::F32 => 2,
|
||||
ValueType::F64 => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_std::convert::TryFrom<u8> for ValueType {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(val: u8) -> sp_std::result::Result<ValueType, ()> {
|
||||
match val {
|
||||
0 => Ok(Self::I32),
|
||||
1 => Ok(Self::I64),
|
||||
2 => Ok(Self::F32),
|
||||
3 => Ok(Self::F64),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Values supported by Substrate on the boundary between host/Wasm.
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
#[derive(PartialEq, Debug, Clone, Copy, codec::Encode, codec::Decode)]
|
||||
pub enum Value {
|
||||
/// A 32-bit integer.
|
||||
I32(i32),
|
||||
@@ -71,6 +96,14 @@ impl Value {
|
||||
Value::F64(_) => ValueType::F64,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `Self` as `i32`.
|
||||
pub fn as_i32(&self) -> Option<i32> {
|
||||
match self {
|
||||
Self::I32(val) => Some(*val),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides `Sealed` trait to prevent implementing trait `PointerType` outside of this crate.
|
||||
@@ -298,6 +331,12 @@ pub trait Sandbox {
|
||||
raw_env_def: &[u8],
|
||||
state: u32,
|
||||
) -> Result<u32>;
|
||||
|
||||
/// Get the value from a global with the given `name`. The sandbox is determined by the
|
||||
/// given `instance_idx` instance.
|
||||
///
|
||||
/// Returns `Some(_)` when the requested global variable could be found.
|
||||
fn get_global_val(&self, instance_idx: u32, name: &str) -> Result<Option<Value>>;
|
||||
}
|
||||
|
||||
/// Something that provides implementations for host functions.
|
||||
@@ -409,9 +448,37 @@ impl ReadPrimitive<u64> for &mut dyn FunctionContext {
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed value that can be returned from a function.
|
||||
///
|
||||
/// Basically a `TypedValue` plus `Unit`, for functions which return nothing.
|
||||
#[derive(Clone, Copy, PartialEq, codec::Encode, codec::Decode, Debug)]
|
||||
pub enum ReturnValue {
|
||||
/// For returning nothing.
|
||||
Unit,
|
||||
/// For returning some concrete value.
|
||||
Value(Value),
|
||||
}
|
||||
|
||||
impl From<Value> for ReturnValue {
|
||||
fn from(v: Value) -> ReturnValue {
|
||||
ReturnValue::Value(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl ReturnValue {
|
||||
/// Maximum number of bytes `ReturnValue` might occupy when serialized with `SCALE`.
|
||||
///
|
||||
/// Breakdown:
|
||||
/// 1 byte for encoding unit/value variant
|
||||
/// 1 byte for encoding value type
|
||||
/// 8 bytes for encoding the biggest value types available in wasm: f64, i64.
|
||||
pub const ENCODED_MAX_SIZE: usize = 10;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codec::Encode;
|
||||
|
||||
#[test]
|
||||
fn pointer_offset_works() {
|
||||
@@ -425,4 +492,11 @@ mod tests {
|
||||
assert_eq!(ptr.offset(10).unwrap(), Pointer::new(80));
|
||||
assert_eq!(ptr.offset(32).unwrap(), Pointer::new(256));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn return_value_encoded_max_size() {
|
||||
let encoded = ReturnValue::Value(Value::I64(-1)).encode();
|
||||
assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user