Last active
January 2, 2018 15:44
-
-
Save pepyakin/74c5600c09b3b20326ab3f55dc1324fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(prelude_import)] | |
#![no_std] | |
// Copyright 2017 Parity Technologies (UK) Ltd. | |
// This file is part of Polkadot. | |
// Polkadot is free software: you can redistribute it and/or modify | |
// it under the terms of the GNU General Public License as published by | |
// the Free Software Foundation, either version 3 of the License, or | |
// (at your option) any later version. | |
// Polkadot is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// You should have received a copy of the GNU General Public License | |
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. | |
//! Temporary crate for contracts implementations. | |
//! | |
//! This will be replaced with WASM contracts stored on-chain. | |
//! ** NOTE *** | |
//! This is entirely deprecated with the idea of a single-module Wasm module for state transition. | |
//! The dispatch table should be replaced with the specific functions needed: | |
//! - execute_block(bytes) | |
//! - init_block(PrevBlock?) -> InProgressBlock | |
//! - add_transaction(InProgressBlock) -> InProgressBlock | |
//! I leave it as is for now as it might be removed before this is ever done. | |
#![warn(missing_docs)] | |
#[prelude_import] | |
use std::prelude::v1::*; | |
#[macro_use] | |
extern crate std as std; | |
extern crate polkadot_primitives as primitives; | |
extern crate polkadot_serializer as serializer; | |
extern crate polkadot_state_machine as state_machine; | |
extern crate serde; | |
extern crate parity_wasm; | |
extern crate byteorder; | |
#[macro_use] | |
extern crate error_chain; | |
#[macro_use] | |
mod wasm_utils { | |
//! Rust implementation of Polkadot contracts. | |
use std::sync::Arc; | |
use std::collections::HashMap; | |
pub use std::result; | |
pub use parity_wasm::elements::{ValueType, Module}; | |
pub use parity_wasm::interpreter::{RuntimeValue, UserFunctionDescriptor, UserFunctionExecutor, | |
UserDefinedElements, env_native_module, DummyUserError, | |
ExecutionParams, UserError}; | |
pub use parity_wasm::builder; | |
use parity_wasm::interpreter; | |
pub type Error = interpreter::Error<DummyUserError>; | |
pub type MemoryInstance = interpreter::MemoryInstance<DummyUserError>; | |
pub type ModuleInstance = interpreter::ModuleInstance<DummyUserError>; | |
pub type CallerContext<'a> = interpreter::CallerContext<'a, DummyUserError>; | |
pub trait ConvertibleToWasm { | |
const VALUE_TYPE: ValueType; | |
type NativeType; | |
fn to_runtime_value(self) -> RuntimeValue; | |
} | |
impl ConvertibleToWasm for i32 { | |
type NativeType = i32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self) | |
} | |
} | |
impl ConvertibleToWasm for u32 { | |
type NativeType = u32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self as i32) | |
} | |
} | |
impl ConvertibleToWasm for i64 { | |
type NativeType = i64; | |
const VALUE_TYPE: ValueType = ValueType::I64; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I64(self) | |
} | |
} | |
impl ConvertibleToWasm for u64 { | |
type NativeType = u64; | |
const VALUE_TYPE: ValueType = ValueType::I64; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I64(self as i64) | |
} | |
} | |
impl ConvertibleToWasm for f32 { | |
type NativeType = f32; | |
const VALUE_TYPE: ValueType = ValueType::F32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::F32(self) | |
} | |
} | |
impl ConvertibleToWasm for f64 { | |
type NativeType = f64; | |
const VALUE_TYPE: ValueType = ValueType::F64; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::F64(self) | |
} | |
} | |
impl ConvertibleToWasm for isize { | |
type NativeType = i32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self as i32) | |
} | |
} | |
impl ConvertibleToWasm for usize { | |
type NativeType = u32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self as u32 as i32) | |
} | |
} | |
impl<T> ConvertibleToWasm for *const T { | |
type NativeType = u32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self as isize as i32) | |
} | |
} | |
impl<T> ConvertibleToWasm for *mut T { | |
type NativeType = u32; | |
const VALUE_TYPE: ValueType = ValueType::I32; | |
fn to_runtime_value(self) -> RuntimeValue { | |
RuntimeValue::I32(self as isize as i32) | |
} | |
} | |
#[macro_export] | |
macro_rules! convert_args(( ) => ( [ ] ) ; ( $ ( $ t : ty ) , * ) => ( | |
[ | |
$ ( | |
{ | |
use $ crate :: wasm_utils :: ConvertibleToWasm ; | |
< $ t > :: VALUE_TYPE } , ) * ] ) ;); | |
#[macro_export] | |
macro_rules! convert_fn(( $ name : ident ( $ ( $ params : ty ) , * ) ) => | |
( | |
$ crate :: wasm_utils :: UserFunctionDescriptor :: | |
Static ( | |
stringify ! ( $ name ) , & convert_args ! ( | |
$ ( $ params ) , * ) , None ) ) ; ( | |
$ name : ident ( $ ( $ params : ty ) , * ) -> $ | |
returns : ty ) => ( | |
$ crate :: wasm_utils :: UserFunctionDescriptor :: | |
Static ( | |
stringify ! ( $ name ) , & convert_args ! ( | |
$ ( $ params ) , * ) , Some ( | |
{ | |
use $ crate :: wasm_utils :: ConvertibleToWasm ; < | |
$ returns > :: VALUE_TYPE } ) ) ) ;); | |
#[macro_export] | |
macro_rules! reverse_params(( | |
$ body : tt , $ self : ident , $ context : | |
ident , $ ( $ names : ident : $ params : ty ) | |
, * ) => ( | |
reverse_params ! ( | |
$ body $ self $ context [ | |
$ ( $ names : $ params ) , * ] ) ; ) ; ( | |
$ body : tt $ self : ident $ context : ident [ | |
] $ ( $ names : ident : $ params : ty ) , * ) | |
=> ( | |
{ | |
$ ( | |
let $ names : < $ params as $ crate :: | |
wasm_utils :: ConvertibleToWasm > :: | |
NativeType = match $ context . value_stack . | |
pop_as ( ) { | |
Ok ( value ) => value , Err ( error ) => | |
return Err ( error . into ( ) ) , } ; ) * $ | |
body } ) ; ( | |
$ body : tt $ self : ident $ context : ident [ | |
$ name : ident : $ param : ty $ ( | |
, $ names : ident : $ params : ty ) * ] $ ( | |
$ reversed_names : ident : $ reversed_params : | |
ty ) , * ) => ( | |
reverse_params ! ( | |
$ body $ self $ context [ | |
$ ( $ names : $ params ) , * ] $ name : $ | |
param $ ( | |
, $ reversed_names : $ reversed_params ) * ) ; | |
) ;); | |
#[macro_export] | |
macro_rules! marshall(( | |
$ context : ident , $ self : ident , ( | |
$ ( $ names : ident : $ params : ty ) , * ) -> $ | |
returns : ty => $ body : tt ) => ( | |
{ | |
let r : < $ returns as $ crate :: wasm_utils :: | |
ConvertibleToWasm > :: NativeType = reverse_params ! | |
( | |
$ body , $ self , $ context , $ ( $ names : $ params | |
) , * ) ; Ok ( | |
Some ( | |
{ | |
use $ crate :: wasm_utils :: ConvertibleToWasm ; r . | |
to_runtime_value ( ) } ) ) } ) ; ( | |
$ context : ident , $ self : ident , ( | |
$ ( $ names : ident : $ params : ty ) , * ) => $ | |
body : tt ) => ( | |
{ | |
reverse_params ! ( | |
$ body , $ self , $ context , $ ( $ names : $ params | |
) , * ) ; Ok ( None ) } )); | |
#[macro_export] | |
macro_rules! dispatch(( | |
$ objectname : ident , $ ( | |
$ name : ident ( | |
$ ( $ names : ident : $ params : ty ) , * ) $ ( | |
-> $ returns : ty ) * => $ body : tt ) , * ) => ( | |
fn execute ( | |
& mut self , name : & str , context : $ crate :: | |
wasm_utils :: CallerContext ) -> $ crate :: | |
wasm_utils :: result :: Result < Option < $ crate :: | |
wasm_utils :: RuntimeValue > , $ crate :: wasm_utils | |
:: Error > { | |
let $ objectname = self ; match name { | |
$ ( | |
stringify ! ( $ name ) => marshall ! ( | |
context , $ objectname , ( | |
$ ( $ names : $ params ) , * ) $ ( -> $ returns ) * | |
=> $ body ) , ) * _ => panic ! ( ) } } ) ;); | |
#[macro_export] | |
macro_rules! signatures(( | |
$ ( | |
$ name : ident ( $ ( $ params : ty ) , * ) $ ( | |
-> $ returns : ty ) * ) , * ) => ( | |
const SIGNATURES : & 'static [ | |
$ crate :: wasm_utils :: UserFunctionDescriptor ] | |
= & [ | |
$ ( | |
convert_fn ! ( | |
$ name ( $ ( $ params ) , * ) $ ( -> $ returns ) * | |
) , ) * ] ; ) ;); | |
pub trait IntoUserDefinedElements { | |
fn into_user_defined_elements(&mut self) -> UserDefinedElements<DummyUserError>; | |
} | |
#[macro_export] | |
macro_rules! impl_function_executor(( | |
$ objectname : ident : $ structname : | |
ty , $ ( | |
$ name : ident ( | |
$ ( $ names : ident : $ params : ty ) | |
, * ) $ ( -> $ returns : ty ) * => $ | |
body : tt ) , * => $ ( $ pre : tt ) + | |
) => ( | |
impl $ ( $ pre ) + $ crate :: | |
wasm_utils :: UserFunctionExecutor < $ | |
crate :: wasm_utils :: DummyUserError | |
> for $ structname { | |
dispatch ! ( | |
$ objectname , $ ( | |
$ name ( $ ( $ names : $ params ) , * | |
) $ ( -> $ returns ) * => $ body ) , * | |
) ; } impl $ ( $ pre ) + $ structname | |
{ | |
signatures ! ( | |
$ ( | |
$ name ( $ ( $ params ) , * ) $ ( | |
-> $ returns ) * ) , * ) ; } impl $ ( | |
$ pre ) + $ crate :: wasm_utils :: | |
IntoUserDefinedElements for $ | |
structname { | |
fn into_user_defined_elements ( | |
& mut self ) -> UserDefinedElements < | |
$ crate :: wasm_utils :: | |
DummyUserError > { | |
$ crate :: wasm_utils :: | |
UserDefinedElements { | |
executor : Some ( self ) , globals : | |
HashMap :: new ( ) , functions : :: | |
std :: borrow :: Cow :: from ( | |
Self :: SIGNATURES ) , } } } ) ;); | |
struct DummyUserFunctionExecutor; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::std::clone::Clone for DummyUserFunctionExecutor { | |
#[inline] | |
fn clone(&self) -> DummyUserFunctionExecutor { | |
match *self { | |
DummyUserFunctionExecutor => DummyUserFunctionExecutor, | |
} | |
} | |
} | |
impl<E: UserError> interpreter::UserFunctionExecutor<E> for DummyUserFunctionExecutor { | |
fn execute( | |
&mut self, | |
_name: &str, | |
_context: interpreter::CallerContext<E>, | |
) -> result::Result<Option<interpreter::RuntimeValue>, interpreter::Error<E>> { | |
{ | |
::rt::begin_panic("not yet implemented", &("src/wasm_utils.rs", 160u32, 2u32)) | |
} | |
} | |
} | |
pub trait AddModuleWithoutFullDependentInstance { | |
fn add_module_by_sigs( | |
&self, | |
name: &str, | |
module: Module, | |
functions: HashMap<&str, &'static [UserFunctionDescriptor]>, | |
) -> result::Result< | |
Arc<interpreter::ModuleInstance<DummyUserError>>, | |
interpreter::Error<DummyUserError>, | |
>; | |
fn params_with_external<'a, 'b: 'a>( | |
&'b self, | |
externals_name: &str, | |
externals: &'a mut IntoUserDefinedElements, | |
) -> ExecutionParams<'a, DummyUserError>; | |
} | |
impl AddModuleWithoutFullDependentInstance for interpreter::ProgramInstance<DummyUserError> { | |
fn add_module_by_sigs( | |
&self, | |
name: &str, | |
module: Module, | |
functions: HashMap<&str, &'static [UserFunctionDescriptor]>, | |
) -> result::Result< | |
Arc<interpreter::ModuleInstance<DummyUserError>>, | |
interpreter::Error<DummyUserError>, | |
> { | |
let mut dufe = ::vec::from_elem(DummyUserFunctionExecutor, functions.len()); | |
let dufe_refs = dufe.iter_mut().collect::<Vec<_>>(); | |
let fake_module_map = | |
functions.into_iter().zip(dufe_refs.into_iter()).map(|((dep_mod_name, | |
functions), | |
dufe)| | |
{ | |
let fake_module = | |
Arc::new(interpreter::env_native_module(self.module(dep_mod_name).unwrap(), | |
UserDefinedElements{executor: | |
Some(dufe), | |
globals: | |
HashMap::new(), | |
functions: | |
::std::borrow::Cow::from(functions),}).unwrap()); | |
let fake_module: | |
Arc<interpreter::ModuleInstanceInterface<_>> = | |
fake_module; | |
(dep_mod_name.into(), | |
fake_module) | |
}).collect::<HashMap<_, | |
_>>(); | |
self.add_module(name, module, Some(&fake_module_map)) | |
} | |
fn params_with_external<'a, 'b: 'a>( | |
&'b self, | |
externals_name: &str, | |
externals: &'a mut IntoUserDefinedElements, | |
) -> ExecutionParams<'a, DummyUserError> { | |
interpreter::ExecutionParams::with_external( | |
externals_name.into(), | |
Arc::new( | |
interpreter::env_native_module( | |
self.module(externals_name).unwrap(), | |
externals.into_user_defined_elements(), | |
).unwrap(), | |
), | |
) | |
} | |
} | |
#[macro_export] | |
macro_rules! map(( $ ( $ name : expr => $ value : expr ) , * ) => ( | |
vec ! [ $ ( ( $ name , $ value ) ) , * ] . into_iter ( ) | |
. collect ( ) )); | |
} | |
mod wasm_executor { | |
//! Rust implementation of Polkadot contracts. | |
use parity_wasm::{deserialize_buffer, ModuleInstanceInterface, ProgramInstance}; | |
use parity_wasm::interpreter::ItemIndex; | |
use parity_wasm::RuntimeValue::{I32, I64}; | |
use std::collections::HashMap; | |
use primitives::contract::CallData; | |
use state_machine::{Externalities, CodeExecutor}; | |
use error::{Error, ErrorKind, Result}; | |
use std::sync::Arc; | |
use wasm_utils::{ModuleInstance, MemoryInstance, UserDefinedElements, | |
AddModuleWithoutFullDependentInstance}; | |
struct Heap { | |
end: u32, | |
} | |
impl Heap { | |
fn new() -> Self { | |
Heap { end: 1024 } | |
} | |
fn allocate(&mut self, size: u32) -> u32 { | |
let r = self.end; | |
self.end += size; | |
r | |
} | |
fn deallocate(&mut self, _offset: u32) {} | |
} | |
struct FunctionExecutor<'e, E: Externalities + 'e> { | |
heap: Heap, | |
memory: Arc<MemoryInstance>, | |
ext: &'e mut E, | |
} | |
impl<'e, E: Externalities> FunctionExecutor<'e, E> { | |
fn new(m: &Arc<ModuleInstance>, e: &'e mut E) -> Self { | |
FunctionExecutor { | |
heap: Heap::new(), | |
memory: Arc::clone(&m.memory(ItemIndex::Internal(0)).unwrap()), | |
ext: e, | |
} | |
} | |
} | |
impl<'e, E: Externalities + 'e> ::wasm_utils::UserFunctionExecutor<::wasm_utils::DummyUserError> | |
for FunctionExecutor<'e, E> { | |
fn execute( | |
&mut self, | |
name: &str, | |
context: ::wasm_utils::CallerContext, | |
) -> ::wasm_utils::result::Result<Option<::wasm_utils::RuntimeValue>, ::wasm_utils::Error> { | |
let this = self; | |
match name { | |
"imported" => { | |
let r: <u64 as ::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let n: | |
<u64 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
::io::_print(::std::fmt::Arguments::new_v1_formatted( | |
&["imported ", "\n"], | |
&match (&n,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Debug::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)); | |
n + 1 | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
"ext_memcpy" => { | |
let r: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let count: | |
<usize as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let src: | |
<*const u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let dest: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
this.memory.copy_nonoverlapping(src as usize, | |
dest as usize, | |
count as | |
usize).unwrap(); | |
::io::_print(::std::fmt::Arguments::new_v1_formatted(&["memcpy ", | |
" from ", | |
", ", | |
" bytes\n"], | |
&match (&dest, | |
&src, | |
&count) | |
{ | |
(__arg0, | |
__arg1, | |
__arg2) | |
=> | |
[::std::fmt::ArgumentV1::new(__arg0, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg1, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg2, | |
::std::fmt::Display::fmt)], | |
}, | |
&[::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(0usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(1usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(2usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}])); | |
dest | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
"ext_memmove" => { | |
let r: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let count: | |
<usize as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let src: | |
<*const u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let dest: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
::io::_print(::std::fmt::Arguments::new_v1_formatted(&["memmove ", | |
" from ", | |
", ", | |
" bytes\n"], | |
&match (&dest, | |
&src, | |
&count) | |
{ | |
(__arg0, | |
__arg1, | |
__arg2) | |
=> | |
[::std::fmt::ArgumentV1::new(__arg0, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg1, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg2, | |
::std::fmt::Display::fmt)], | |
}, | |
&[::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(0usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(1usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(2usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}])); | |
dest | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
"ext_memset" => { | |
let r: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let count: | |
<usize as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let val: | |
<i32 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let dest: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
::io::_print(::std::fmt::Arguments::new_v1_formatted(&["memset ", | |
" with ", | |
", ", | |
" bytes\n"], | |
&match (&dest, | |
&val, | |
&count) | |
{ | |
(__arg0, | |
__arg1, | |
__arg2) | |
=> | |
[::std::fmt::ArgumentV1::new(__arg0, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg1, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg2, | |
::std::fmt::Display::fmt)], | |
}, | |
&[::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(0usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(1usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(2usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}])); | |
dest | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
"ext_malloc" => { | |
let r: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let size: | |
<usize as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
let r = this.heap.allocate(size); | |
::io::_print(::std::fmt::Arguments::new_v1_formatted(&["malloc ", | |
" bytes at ", | |
"\n"], | |
&match (&size, | |
&r) | |
{ | |
(__arg0, | |
__arg1) | |
=> | |
[::std::fmt::ArgumentV1::new(__arg0, | |
::std::fmt::Display::fmt), | |
::std::fmt::ArgumentV1::new(__arg1, | |
::std::fmt::Display::fmt)], | |
}, | |
&[::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(0usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}, | |
::std::fmt::rt::v1::Argument{position: | |
::std::fmt::rt::v1::Position::At(1usize), | |
format: | |
::std::fmt::rt::v1::FormatSpec{fill: | |
' ', | |
align: | |
::std::fmt::rt::v1::Alignment::Unknown, | |
flags: | |
0u32, | |
precision: | |
::std::fmt::rt::v1::Count::Implied, | |
width: | |
::std::fmt::rt::v1::Count::Implied,},}])); | |
r | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
"ext_free" => { | |
{ | |
let addr: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
this.heap.deallocate(addr); | |
::io::_print(::std::fmt::Arguments::new_v1_formatted( | |
&["free ", "\n"], | |
&match (&addr,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Display::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
} | |
}; | |
Ok(None) | |
} | |
"set_storage" => { | |
{ | |
let value_len: | |
<i32 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let value_data: | |
<*const u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let key_len: | |
<i32 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let key_data: | |
<*const u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
if let (Ok(key), Ok(value)) = | |
( | |
this.memory.get(key_data, key_len as usize), | |
this.memory.get(value_data, value_len as usize), | |
) | |
{ | |
this.ext.set_storage(0, key, value); | |
} | |
} | |
}; | |
Ok(None) | |
} | |
"get_allocated_storage" => { | |
let r: | |
<*mut u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
{ | |
let written_out: | |
<*mut i32 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let key_len: | |
<i32 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
let key_data: | |
<*const u8 as | |
::wasm_utils::ConvertibleToWasm>::NativeType = | |
match context.value_stack.pop_as() { | |
Ok(value) => value, | |
Err(error) => return Err(error.into()), | |
}; | |
{ | |
let (offset, written) = | |
if let Ok(key) = | |
this.memory.get(key_data, | |
key_len as usize) { | |
if let Ok(value) = | |
this.ext.storage(0, &key) { | |
let offset = | |
this.heap.allocate(value.len() | |
as u32) | |
as u32; | |
let _ = | |
this.memory.set(offset, | |
value); | |
(offset, value.len() as u32) | |
} else { (0, 0) } | |
} else { (0, 0) }; | |
if written > 0 { | |
use byteorder::{LittleEndian, ByteOrder}; | |
let mut r = [0u8; 4]; | |
LittleEndian::write_u32(&mut r, written); | |
let _ = this.memory.set(written_out, &r); | |
} | |
offset as u32 | |
} | |
}; | |
Ok(Some({ | |
use wasm_utils::ConvertibleToWasm; | |
r.to_runtime_value() | |
})) | |
} | |
_ => { | |
::rt::begin_panic("explicit panic", &("src/wasm_executor.rs", 64u32, 0u32)) | |
} | |
} | |
} | |
} | |
impl<'e, E: Externalities + 'e> FunctionExecutor<'e, E> { | |
const SIGNATURES: &'static [::wasm_utils::UserFunctionDescriptor] = | |
&[ | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"imported", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<u64>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<u64>::VALUE_TYPE | |
}), | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"ext_memcpy", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*const u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<usize>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}), | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"ext_memmove", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*const u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<usize>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}), | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"ext_memset", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<i32>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<usize>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}), | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"ext_malloc", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<usize>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}), | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"ext_free", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}, | |
], | |
None, | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"set_storage", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*const u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<i32>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*const u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<i32>::VALUE_TYPE | |
}, | |
], | |
None, | |
), | |
::wasm_utils::UserFunctionDescriptor::Static( | |
"get_allocated_storage", | |
&[ | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*const u8>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<i32>::VALUE_TYPE | |
}, | |
{ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut i32>::VALUE_TYPE | |
}, | |
], | |
Some({ | |
use wasm_utils::ConvertibleToWasm; | |
<*mut u8>::VALUE_TYPE | |
}), | |
), | |
]; | |
} | |
impl<'e, E: Externalities + 'e> ::wasm_utils::IntoUserDefinedElements for FunctionExecutor<'e, E> { | |
fn into_user_defined_elements( | |
&mut self, | |
) -> UserDefinedElements<::wasm_utils::DummyUserError> { | |
::wasm_utils::UserDefinedElements { | |
executor: Some(self), | |
globals: HashMap::new(), | |
functions: ::std::borrow::Cow::from(Self::SIGNATURES), | |
} | |
} | |
} | |
/// Dummy rust executor for contracts. | |
/// | |
/// Instead of actually executing the provided code it just | |
/// dispatches the calls to pre-defined hardcoded implementations in rust. | |
pub struct WasmExecutor; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::std::fmt::Debug for WasmExecutor { | |
fn fmt(&self, __arg_0: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
match *self { | |
WasmExecutor => { | |
let mut builder = __arg_0.debug_tuple("WasmExecutor"); | |
builder.finish() | |
} | |
} | |
} | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::std::default::Default for WasmExecutor { | |
#[inline] | |
fn default() -> WasmExecutor { | |
WasmExecutor | |
} | |
} | |
impl CodeExecutor for WasmExecutor { | |
type Error = Error; | |
fn call<E: Externalities>( | |
&self, | |
ext: &mut E, | |
method: &str, | |
data: &CallData, | |
) -> Result<u64> { | |
let code = match ext.code() { | |
Ok(e) => e.to_owned(), | |
Err(e) => Err(ErrorKind::Externalities(Box::new(e)))?, | |
}; | |
let program = ProgramInstance::new().unwrap(); | |
let module = deserialize_buffer(code).expect("Failed to load module"); | |
let module = program | |
.add_module_by_sigs( | |
"test", | |
module, | |
<[_]>::into_vec(box [("env", FunctionExecutor::<E>::SIGNATURES)]) | |
.into_iter() | |
.collect(), | |
) | |
.expect("Failed to initialize module"); | |
let mut fec = FunctionExecutor::new(&module, ext); | |
let size = data.0.len() as u32; | |
let offset = fec.heap.allocate(size); | |
module | |
.memory(ItemIndex::Internal(0)) | |
.unwrap() | |
.set(offset, &data.0) | |
.unwrap(); | |
let r = module | |
.execute_export( | |
method, | |
program | |
.params_with_external("env", &mut fec) | |
.add_argument(I32(offset as i32)) | |
.add_argument(I32(size as i32)), | |
) | |
.map_err(|_| ErrorKind::Runtime.into()) | |
.and_then(|i| if let Some(I64(r)) = i { | |
Ok(r as u64) | |
} else { | |
Err(ErrorKind::InvalidReturn.into()) | |
}); | |
r | |
} | |
} | |
} | |
pub mod error { | |
//! Rust executor possible errors. | |
use serializer; | |
use state_machine; | |
/// The Error type. | |
/// | |
/// This tuple struct is made of two elements: | |
/// | |
/// - an `ErrorKind` which is used to determine the type of the error. | |
/// - An internal `State`, not meant for direct use outside of `error_chain` | |
/// internals, containing: | |
/// - a backtrace, generated when the error is created. | |
/// - an error chain, used for the implementation of `Error::cause()`. | |
pub struct Error( | |
/// The kind of the error. | |
pub ErrorKind, | |
/// Contains the error chain and the backtrace. | |
#[doc(hidden)] | |
pub ::State | |
); | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::std::fmt::Debug for Error { | |
fn fmt(&self, __arg_0: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
match *self { | |
Error(ref __self_0_0, ref __self_0_1) => { | |
let mut builder = __arg_0.debug_tuple("Error"); | |
let _ = builder.field(&&(*__self_0_0)); | |
let _ = builder.field(&&(*__self_0_1)); | |
builder.finish() | |
} | |
} | |
} | |
} | |
impl ::ChainedError for Error { | |
type ErrorKind = ErrorKind; | |
fn new(kind: ErrorKind, state: ::State) -> Error { | |
Error(kind, state) | |
} | |
fn from_kind(kind: Self::ErrorKind) -> Self { | |
Self::from_kind(kind) | |
} | |
fn with_chain<E, K>(error: E, kind: K) -> Self | |
where | |
E: ::std::error::Error + Send + 'static, | |
K: Into<Self::ErrorKind>, | |
{ | |
Self::with_chain(error, kind) | |
} | |
fn kind(&self) -> &Self::ErrorKind { | |
self.kind() | |
} | |
fn iter(&self) -> ::Iter { | |
::Iter::new(Some(self)) | |
} | |
fn chain_err<F, EK>(self, error: F) -> Self | |
where | |
F: FnOnce() -> EK, | |
EK: Into<ErrorKind>, | |
{ | |
self.chain_err(error) | |
} | |
fn backtrace(&self) -> Option<&::Backtrace> { | |
self.backtrace() | |
} | |
#[allow(unknown_lints, unused_doc_comment)] | |
fn extract_backtrace( | |
e: &(::std::error::Error + Send + 'static), | |
) -> Option<::std::sync::Arc<::Backtrace>> { | |
if let Some(e) = e.downcast_ref::<Error>() { | |
return e.1.backtrace.clone(); | |
} | |
None | |
} | |
} | |
#[allow(dead_code)] | |
impl Error { | |
/// Constructs an error from a kind, and generates a backtrace. | |
pub fn from_kind(kind: ErrorKind) -> Error { | |
Error(kind, ::State::default()) | |
} | |
/// Constructs a chained error from another error and a kind, and generates a backtrace. | |
pub fn with_chain<E, K>(error: E, kind: K) -> Error | |
where | |
E: ::std::error::Error + Send + 'static, | |
K: Into<ErrorKind>, | |
{ | |
Error::with_boxed_chain(Box::new(error), kind) | |
} | |
/// Construct a chained error from another boxed error and a kind, and generates a backtrace | |
pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send>, kind: K) -> Error | |
where | |
K: Into<ErrorKind>, | |
{ | |
Error(kind.into(), ::State::new::<Error>(error)) | |
} | |
/// Returns the kind of the error. | |
pub fn kind(&self) -> &ErrorKind { | |
&self.0 | |
} | |
/// Iterates over the error chain. | |
pub fn iter(&self) -> ::Iter { | |
::ChainedError::iter(self) | |
} | |
/// Returns the backtrace associated with this error. | |
pub fn backtrace(&self) -> Option<&::Backtrace> { | |
self.1.backtrace() | |
} | |
/// Extends the error chain with a new entry. | |
pub fn chain_err<F, EK>(self, error: F) -> Error | |
where | |
F: FnOnce() -> EK, | |
EK: Into<ErrorKind>, | |
{ | |
Error::with_chain(self, Self::from_kind(error().into())) | |
} | |
} | |
impl ::std::error::Error for Error { | |
fn description(&self) -> &str { | |
self.0.description() | |
} | |
#[allow(unknown_lints, unused_doc_comment)] | |
fn cause(&self) -> Option<&::std::error::Error> { | |
match self.1.next_error { | |
Some(ref c) => Some(&**c), | |
None => { | |
match self.0 { | |
#[doc = "Unserializable Data"] | |
ErrorKind::InvalidData(ref foreign_err) => foreign_err.cause(), | |
_ => None, | |
} | |
} | |
} | |
} | |
} | |
impl ::std::fmt::Display for Error { | |
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
::std::fmt::Display::fmt(&self.0, f) | |
} | |
} | |
#[doc = "Unserializable Data"] | |
impl From<serializer::Error> for Error { | |
fn from(e: serializer::Error) -> Self { | |
Error::from_kind(ErrorKind::InvalidData(e)) | |
} | |
} | |
impl From<ErrorKind> for Error { | |
fn from(e: ErrorKind) -> Self { | |
Error::from_kind(e) | |
} | |
} | |
impl<'a> From<&'a str> for Error { | |
fn from(s: &'a str) -> Self { | |
Error::from_kind(s.into()) | |
} | |
} | |
impl From<String> for Error { | |
fn from(s: String) -> Self { | |
Error::from_kind(s.into()) | |
} | |
} | |
impl ::std::ops::Deref for Error { | |
type Target = ErrorKind; | |
fn deref(&self) -> &Self::Target { | |
&self.0 | |
} | |
} | |
#[doc = r" The kind of an error."] | |
pub enum ErrorKind { | |
#[doc = r" A convenient variant for String."] | |
Msg(String), | |
#[doc = "Unserializable Data"] | |
InvalidData(serializer::Error), | |
#[doc = r" Method is not found"] | |
MethodNotFound(String), | |
#[doc = r" Code is invalid (expected single byte)"] | |
InvalidCode(Vec<u8>), | |
#[doc = r" Externalities have failed."] | |
Externalities(Box<state_machine::Error>), | |
#[doc = r" Invalid return type."] | |
InvalidReturn, | |
#[doc = r" Runtime failed."] | |
Runtime, | |
#[doc(hidden)] | |
__Nonexhaustive {}, | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::std::fmt::Debug for ErrorKind { | |
fn fmt(&self, __arg_0: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
match (&*self,) { | |
(&ErrorKind::Msg(ref __self_0),) => { | |
let mut builder = __arg_0.debug_tuple("Msg"); | |
let _ = builder.field(&&(*__self_0)); | |
builder.finish() | |
} | |
(&ErrorKind::InvalidData(ref __self_0),) => { | |
let mut builder = __arg_0.debug_tuple("InvalidData"); | |
let _ = builder.field(&&(*__self_0)); | |
builder.finish() | |
} | |
(&ErrorKind::MethodNotFound(ref __self_0),) => { | |
let mut builder = __arg_0.debug_tuple("MethodNotFound"); | |
let _ = builder.field(&&(*__self_0)); | |
builder.finish() | |
} | |
(&ErrorKind::InvalidCode(ref __self_0),) => { | |
let mut builder = __arg_0.debug_tuple("InvalidCode"); | |
let _ = builder.field(&&(*__self_0)); | |
builder.finish() | |
} | |
(&ErrorKind::Externalities(ref __self_0),) => { | |
let mut builder = __arg_0.debug_tuple("Externalities"); | |
let _ = builder.field(&&(*__self_0)); | |
builder.finish() | |
} | |
(&ErrorKind::InvalidReturn,) => { | |
let mut builder = __arg_0.debug_tuple("InvalidReturn"); | |
builder.finish() | |
} | |
(&ErrorKind::Runtime,) => { | |
let mut builder = __arg_0.debug_tuple("Runtime"); | |
builder.finish() | |
} | |
(&ErrorKind::__Nonexhaustive {},) => { | |
let mut builder = __arg_0.debug_struct("__Nonexhaustive"); | |
builder.finish() | |
} | |
} | |
} | |
} | |
#[allow(unknown_lints, unused, unused_doc_comment)] | |
impl ::std::fmt::Display for ErrorKind { | |
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
match *self { | |
#[doc = r" A convenient variant for String."] | |
ErrorKind::Msg(ref s) => { | |
let display_fn = | |
|_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1_formatted( | |
&[""], | |
&match (&s,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Display::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = "Unserializable Data"] | |
ErrorKind::InvalidData(ref err) => { | |
let display_fn = | |
|_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1_formatted( | |
&[""], | |
&match (&err,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Display::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = r" Method is not found"] | |
ErrorKind::MethodNotFound(ref t) => { | |
let display_fn = | |
|_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1_formatted( | |
&["Method not found: \'", "\'"], | |
&match (&t,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Display::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = r" Code is invalid (expected single byte)"] | |
ErrorKind::InvalidCode(ref c) => { | |
let display_fn = |_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1_formatted( | |
&["Invalid Code: "], | |
&match (&c,) { | |
(__arg0,) => { | |
[::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = r" Externalities have failed."] | |
ErrorKind::Externalities(ref e) => { | |
let display_fn = | |
|_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1_formatted( | |
&["Externalities error: "], | |
&match (&e,) { | |
(__arg0,) => { | |
[ | |
::std::fmt::ArgumentV1::new( | |
__arg0, | |
::std::fmt::Display::fmt, | |
), | |
] | |
} | |
}, | |
&[ | |
::std::fmt::rt::v1::Argument { | |
position: ::std::fmt::rt::v1::Position::At(0usize), | |
format: ::std::fmt::rt::v1::FormatSpec { | |
fill: ' ', | |
align: ::std::fmt::rt::v1::Alignment::Unknown, | |
flags: 0u32, | |
precision: ::std::fmt::rt::v1::Count::Implied, | |
width: ::std::fmt::rt::v1::Count::Implied, | |
}, | |
}, | |
], | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = r" Invalid return type."] | |
ErrorKind::InvalidReturn => { | |
let display_fn = |_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1( | |
&["Invalid type returned (should be u64)"], | |
&match () { | |
() | |
=> | |
[], | |
}, | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
#[doc = r" Runtime failed."] | |
ErrorKind::Runtime => { | |
let display_fn = |_, f: &mut ::std::fmt::Formatter| { | |
f.write_fmt(::std::fmt::Arguments::new_v1( | |
&["Runtime error"], | |
&match () { | |
() | |
=> | |
[], | |
}, | |
)) | |
}; | |
display_fn(self, fmt) | |
} | |
_ => Ok(()), | |
} | |
} | |
} | |
#[allow(unknown_lints, unused, unused_doc_comment)] | |
impl ErrorKind { | |
/// A string describing the error kind. | |
pub fn description(&self) -> &str { | |
match *self { | |
#[doc = r" A convenient variant for String."] | |
ErrorKind::Msg(ref s) => &s, | |
#[doc = "Unserializable Data"] | |
ErrorKind::InvalidData(ref err) => ::std::error::Error::description(err), | |
#[doc = r" Method is not found"] | |
ErrorKind::MethodNotFound(ref t) => "method not found", | |
#[doc = r" Code is invalid (expected single byte)"] | |
ErrorKind::InvalidCode(ref c) => "invalid code", | |
#[doc = r" Externalities have failed."] | |
ErrorKind::Externalities(ref e) => "externalities failure", | |
#[doc = r" Invalid return type."] | |
ErrorKind::InvalidReturn => "u64 was not returned", | |
#[doc = r" Runtime failed."] | |
ErrorKind::Runtime => "runtime failure", | |
_ => "", | |
} | |
} | |
} | |
impl<'a> From<&'a str> for ErrorKind { | |
fn from(s: &'a str) -> Self { | |
ErrorKind::Msg(s.to_string()) | |
} | |
} | |
impl From<String> for ErrorKind { | |
fn from(s: String) -> Self { | |
ErrorKind::Msg(s) | |
} | |
} | |
impl From<Error> for ErrorKind { | |
fn from(e: Error) -> Self { | |
e.0 | |
} | |
} | |
/// Additional methods for `Result`, for easy interaction with this crate. | |
pub trait ResultExt<T> { | |
/// If the `Result` is an `Err` then `chain_err` evaluates the closure, | |
/// which returns *some type that can be converted to `ErrorKind`*, boxes | |
/// the original error to store as the cause, then returns a new error | |
/// containing the original error. | |
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, Error> | |
where | |
F: FnOnce() -> EK, | |
EK: Into<ErrorKind>; | |
} | |
impl<T, E> ResultExt<T> for ::std::result::Result<T, E> | |
where | |
E: ::std::error::Error + Send + 'static, | |
{ | |
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, Error> | |
where | |
F: FnOnce() -> EK, | |
EK: Into<ErrorKind>, | |
{ | |
self.map_err(move |e| { | |
let state = ::State::new::<Error>(Box::new(e)); | |
::ChainedError::new(callback().into(), state) | |
}) | |
} | |
} | |
impl<T> ResultExt<T> for ::std::option::Option<T> { | |
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, Error> | |
where | |
F: FnOnce() -> EK, | |
EK: Into<ErrorKind>, | |
{ | |
self.ok_or_else(move || ::ChainedError::from_kind(callback().into())) | |
} | |
} | |
/// Convenient wrapper around `std::Result`. | |
#[allow(unused)] | |
pub type Result<T> = ::std::result::Result<T, Error>; | |
} | |
/// Creates new RustExecutor for contracts. | |
pub fn executor() -> wasm_executor::WasmExecutor { | |
wasm_executor::WasmExecutor::default() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment