-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Changes from 1 commit
4f5c5b6
6237848
293cf5d
66b636e
c7e7456
0cfd67e
3011edf
a74b4fa
6dac275
08f7b26
1ace6b2
27e5fed
13dcd89
84b9f84
7f31899
edf061e
edb6bea
9f59f48
287b29d
1bd55fe
36e254a
cd651a3
a8f9cca
4404846
b1d963a
319d9c0
7ec9221
2934d94
5998aa1
3f4085a
4be0537
01d7019
db1adee
87c54f7
471ea1e
fa35993
a0f64df
e736d46
234297c
3f8a96d
6636520
964659e
8ca1b7b
74156a2
611a7ac
c3afecc
ea4d6c5
709693d
ec1e6b6
5c0ec3d
79ab46f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,14 +17,14 @@ | |
| //! Rust implementation of Polkadot contracts. | ||
|
|
||
| use parity_wasm::{deserialize_buffer, ModuleInstanceInterface}; | ||
| use parity_wasm::interpreter::{ItemIndex, ModuleInstance, MemoryInstance, UserDefinedElements}; | ||
| 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, Mutex}; | ||
| use wasm_utils::program_with_externals; | ||
| use wasm_utils::{program_with_externals, ModuleInstance, MemoryInstance, UserDefinedElements}; | ||
|
|
||
| // user function executor | ||
| #[derive(Default)] | ||
|
|
@@ -74,6 +74,27 @@ function_executor!(this: FunctionExecutor, | |
| ); | ||
|
|
||
|
|
||
| function_executor!(this: FEContext, | ||
| imported(n: u64) -> u64 => { println!("imported {:?}", n); n + 1 }, | ||
| ext_memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { | ||
| this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize).unwrap(); | ||
| println!("memcpy {} from {}, {} bytes", dest, src, count); | ||
| dest | ||
| }, | ||
| ext_memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { println!("memmove {} from {}, {} bytes", dest, src, count); dest }, | ||
| ext_memset(dest: *mut u8, val: i32, count: usize) -> *mut u8 => { println!("memset {} with {}, {} bytes", dest, val, count); dest }, | ||
|
||
| ext_malloc(size: usize) -> *mut u8 => { | ||
| let r = this.allocate(size); | ||
| println!("malloc {} bytes at {}", size, r); | ||
| r | ||
| }, | ||
| ext_free(addr: *mut u8) => { | ||
| this.deallocate(addr); | ||
| println!("free {}", addr) | ||
| } | ||
| ); | ||
|
|
||
|
|
||
| /// Dummy rust executor for contracts. | ||
| /// | ||
| /// Instead of actually executing the provided code it just | ||
|
|
@@ -97,15 +118,16 @@ impl CodeExecutor for WasmExecutor { | |
| Ok(e) => e.to_owned(), | ||
| Err(e) => Err(ErrorKind::Externalities(Box::new(e)))?, | ||
| }; | ||
|
|
||
| let fe_context = Arc::new(Mutex::new(None)); | ||
|
||
| let mut fe = FunctionExecutor { context: Arc::clone(&fe_context) }; | ||
|
|
||
| let externals = UserDefinedElements { | ||
| executor: Some(FunctionExecutor { context: Arc::clone(&fe_context) }), | ||
| executor: Some(&mut fe), | ||
| globals: HashMap::new(), | ||
| functions: ::std::borrow::Cow::from(FunctionExecutor::SIGNATURES), | ||
| }; | ||
|
|
||
| let program = program_with_externals(externals, "env").unwrap(); | ||
| let program = program_with_externals::<FunctionExecutor>(externals, "env").unwrap(); | ||
| let module = deserialize_buffer(code).expect("Failed to load module"); | ||
| let module = program.add_module("test", module, None).expect("Failed to initialize module"); | ||
|
||
| *fe_context.lock().unwrap() = Some(FEContext::new(&module)); | ||
|
|
@@ -131,6 +153,7 @@ mod tests { | |
| use parity_wasm::{deserialize_buffer, ModuleInstanceInterface, ProgramInstance}; | ||
| use parity_wasm::interpreter::{ItemIndex, UserDefinedElements}; | ||
| use parity_wasm::RuntimeValue::{I32, I64}; | ||
| use parity_wasm::interpreter; | ||
|
|
||
| #[derive(Debug, Default)] | ||
| struct TestExternalities; | ||
|
|
@@ -154,16 +177,65 @@ mod tests { | |
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn should_pass_externalities_at_call() { | ||
| let program = ProgramInstance::new().unwrap(); | ||
|
|
||
| let test_module = include_bytes!("../../runtime/target/wasm32-unknown-unknown/release/runtime.compact.wasm"); | ||
| let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); | ||
| let module = program.add_module("test", module, None).expect("Failed to initialize module"); | ||
|
|
||
| let mut fec = FEContext { | ||
| heap_end: 1024, | ||
| memory: Arc::clone(&module.memory(ItemIndex::Internal(0)).unwrap()) | ||
| }; | ||
|
|
||
| let data = b"Hello world"; | ||
| let size = data.len() as u32; | ||
| let offset = fec.allocate(size); | ||
| module.memory(ItemIndex::Internal(0)).unwrap().set(offset, data).unwrap(); | ||
|
|
||
| /* use parity_wasm::builder; | ||
| use std::sync::{Arc, Weak}; | ||
| use parity_wasm::ModuleInstance; | ||
| let env_instance = { | ||
| let module = builder::module().build(); | ||
| let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module).unwrap(); | ||
| instance.instantiate(None).unwrap(); | ||
| Arc::new(instance) | ||
| }; | ||
| */ | ||
|
|
||
| let execute = |fec| module.execute_export( | ||
| "test_data_in", | ||
| interpreter::ExecutionParams::with_external( | ||
| "env".into(), | ||
| Arc::new(interpreter::env_native_module(program.module("env").unwrap(), UserDefinedElements { | ||
| executor: Some(fec), | ||
| globals: HashMap::new(), | ||
| functions: ::std::borrow::Cow::from(FEContext::SIGNATURES), | ||
| }).unwrap()) | ||
| ) | ||
| .add_argument(I32(offset as i32)) | ||
| .add_argument(I32(size as i32)) | ||
| ).unwrap(); | ||
|
|
||
| execute(&mut fec); | ||
|
|
||
| panic!(); | ||
| } | ||
|
|
||
| #[test] | ||
| fn should_pass_freeable_data() { | ||
| let fe_context = Arc::new(Mutex::new(None)); | ||
| let mut fex = FunctionExecutor { context: Arc::clone(&fe_context) }; | ||
| let externals = UserDefinedElements { | ||
| executor: Some(FunctionExecutor { context: Arc::clone(&fe_context) }), | ||
| executor: Some(&mut fex), | ||
| globals: HashMap::new(), | ||
| functions: ::std::borrow::Cow::from(FunctionExecutor::SIGNATURES), | ||
| }; | ||
|
|
||
| let program = program_with_externals(externals, "env").unwrap(); | ||
| let program = program_with_externals::<FunctionExecutor>(externals, "env").unwrap(); | ||
|
|
||
| let test_module = include_bytes!("../../runtime/target/wasm32-unknown-unknown/release/runtime.compact.wasm"); | ||
| let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); | ||
|
|
@@ -184,13 +256,14 @@ mod tests { | |
| #[test] | ||
| fn should_provide_externalities() { | ||
| let fe_context = Arc::new(Mutex::new(None)); | ||
| let mut fex = FunctionExecutor { context: Arc::clone(&fe_context) }; | ||
| let externals = UserDefinedElements { | ||
| executor: Some(FunctionExecutor { context: Arc::clone(&fe_context) }), | ||
| executor: Some(&mut fex), | ||
| globals: HashMap::new(), | ||
| functions: ::std::borrow::Cow::from(FunctionExecutor::SIGNATURES), | ||
| }; | ||
|
|
||
| let program = program_with_externals(externals, "env").unwrap(); | ||
| let program = program_with_externals::<FunctionExecutor>(externals, "env").unwrap(); | ||
|
|
||
| let test_module = include_bytes!("../../runtime/target/wasm32-unknown-unknown/release/runtime.wasm"); | ||
| let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module"); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,19 +20,27 @@ use std::sync::{Arc, Weak}; | |
| pub use std::result; | ||
| pub use parity_wasm::elements::{ValueType}; | ||
| pub use parity_wasm::interpreter::{RuntimeValue, UserFunctionDescriptor, UserFunctionExecutor, | ||
| CallerContext, UserDefinedElements, Error, native_module}; | ||
| pub use parity_wasm::{builder, ProgramInstance, ModuleInstance}; | ||
| UserDefinedElements, env_native_module, DummyUserError}; | ||
| pub use parity_wasm::{builder}; | ||
| use parity_wasm::interpreter; | ||
|
|
||
| pub fn program_with_externals<E: UserFunctionExecutor + 'static>(externals: UserDefinedElements<E>, module_name: &str) -> result::Result<ProgramInstance, Error> { | ||
| let program = ProgramInstance::new(); | ||
| pub type Error = interpreter::Error<DummyUserError>; | ||
| pub type MemoryInstance = interpreter::MemoryInstance<DummyUserError>; | ||
| pub type ProgramInstance = interpreter::ProgramInstance<DummyUserError>; | ||
| pub type ModuleInstance = interpreter::ModuleInstance<DummyUserError>; | ||
| pub type ModuleInstanceInterface = interpreter::ModuleInstanceInterface<DummyUserError>; | ||
| pub type CallerContext<'a> = interpreter::CallerContext<'a, DummyUserError>; | ||
|
|
||
| pub fn program_with_externals<E: UserFunctionExecutor<DummyUserError> + 'static>(externals: UserDefinedElements<DummyUserError>, module_name: &str) -> result::Result<ProgramInstance, Error> { | ||
| let program = ProgramInstance::new().unwrap(); | ||
| let instance = { | ||
| let module = builder::module().build(); | ||
| let mut instance = ModuleInstance::new(Weak::default(), module_name.into(), module)?; | ||
| instance.instantiate(None)?; | ||
| instance | ||
| }; | ||
| let other_instance = native_module(Arc::new(instance), externals)?; | ||
| program.insert_loaded_module(module_name, other_instance)?; | ||
| let other_instance = env_native_module(Arc::new(instance), externals)?; | ||
| // program.insert_loaded_module(module_name, Arc::new(other_instance)); | ||
| Ok(program) | ||
| } | ||
|
|
||
|
|
@@ -102,7 +110,7 @@ macro_rules! dispatch { | |
| $( | ||
| stringify!($name) => marshall!(context, $objectname, ( $( $names : $params ),* ) $( -> $returns )* => $body), | ||
| )* | ||
| n => Err($crate::wasm_utils::Error::Trap(format!("not implemented: {}", n)).into()) | ||
| _ => panic!()//Err($crate::wasm_utils::Error::Trap(format!("not implemented: {}", n)).into()) | ||
| } | ||
| } | ||
| ); | ||
|
|
@@ -122,7 +130,7 @@ macro_rules! signatures { | |
| #[macro_export] | ||
| macro_rules! function_executor { | ||
|
||
| ( $objectname:ident : $structname:ident, $( $name:ident ( $( $names:ident : $params:ty ),* ) $( -> $returns:ty )* => $body:tt ),* ) => ( | ||
| impl $crate::wasm_utils::UserFunctionExecutor for $structname { | ||
| impl $crate::wasm_utils::UserFunctionExecutor<$crate::wasm_utils::DummyUserError> for $structname { | ||
| dispatch!($objectname, $( $name( $( $names : $params ),* ) $( -> $returns )* => $body ),*); | ||
| } | ||
| impl $structname { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
justify unwrap