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:
Bastian Köcher
2020-01-29 16:24:40 +01:00
committed by GitHub
parent ae1e9002d7
commit 4c36143375
23 changed files with 275 additions and 195 deletions
+75 -1
View File
@@ -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);
}
}