Adds function to_substrate_wasm_fn_return_value (#3905)

* Adds function `to_substrate_wasm_fn_return_value`

Instead of replicating this piece of code over and over again, just move
it to a function that does it.

* Feedback

* Comment
This commit is contained in:
Bastian Köcher
2019-10-25 15:18:20 +02:00
committed by Gavin Wood
parent 7c0592a9b6
commit ce71b7554d
13 changed files with 187 additions and 72 deletions
+8 -3
View File
@@ -21,12 +21,17 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine"
sr-primitives = { path = "../sr-primitives" }
sr-version = { path = "../sr-version" }
primitives = { package = "substrate-primitives", path = "../primitives" }
criterion = "0.2.11"
criterion = "0.3.0"
consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" }
codec = { package = "parity-scale-codec", version = "1.0.0" }
trybuild = "1.0.14"
rustversion = "0.1.4"
trybuild = "1.0.17"
rustversion = "1.0.0"
[[bench]]
name = "bench"
harness = false
# We actually don't need the `std` feature in this crate, but the tests require it.
[features]
default = [ "std" ]
std = []
@@ -83,8 +83,7 @@ fn generate_impl_call(
)*
#[allow(deprecated)]
let output = <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*);
#c::runtime_api::Encode::encode(&output)
<#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*)
)
)
}
@@ -175,11 +174,12 @@ fn generate_impl_calls(
/// Generate the dispatch function that is used in native to call into the runtime.
fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
let data = Ident::new("data", Span::call_site());
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
let impl_calls = generate_impl_calls(impls, &data)?
.into_iter()
.map(|(trait_, fn_name, impl_)| {
let name = prefix_function_with_trait(&trait_, &fn_name);
quote!( #name => Some({ #impl_ }), )
quote!( #name => Some(#c::runtime_api::Encode::encode(&{ #impl_ })), )
});
Ok(quote!(
@@ -218,13 +218,7 @@ fn generate_wasm_interface(impls: &[ItemImpl]) -> Result<TokenStream> {
};
let output = { #impl_ };
let res = output.as_ptr() as u64 + ((output.len() as u64) << 32);
// Leak the output vector to avoid it being freed.
// This is fine in a WASM context since the heap
// will be discarded after the call.
#c::runtime_api::mem::forget(output);
res
#c::runtime_api::to_substrate_wasm_fn_return_value(&output)
}
)
});
@@ -93,13 +93,6 @@ fn test_client_side_function_signature() {
RuntimeApiImpl::<TestClient>::same_name_before_version_2;
}
#[test]
fn test_runtime_side_function_signature() {
let _api_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = api::Api_same_name;
let _api_with_version_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 =
api::ApiWithCustomVersion_same_name;
}
#[test]
fn check_runtime_api_info() {
assert_eq!(&Api::<Block>::ID, &runtime_decl_for_Api::ID);
@@ -1,6 +1,6 @@
use sr_primitives::traits::GetNodeBlockType;
use sr_primitives::traits::{GetNodeBlockType, Block as BlockT};
use test_client::runtime::Block;
use client::{decl_runtime_apis, impl_runtime_apis};
use client::{decl_runtime_apis, impl_runtime_apis, runtime_api};
/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
/// trait are done by the `construct_runtime!` macro in a real runtime.
@@ -19,6 +19,18 @@ impl_runtime_apis! {
impl self::Api<Block> for Runtime {
fn test(data: String) {}
}
impl runtime_api::Core<Block> for Runtime {
fn version() -> runtime_api::RuntimeVersion {
unimplemented!()
}
fn execute_block(_: Block) {
unimplemented!()
}
fn initialize_block(_: &<Block as BlockT>::Header) {
unimplemented!()
}
}
}
fn main() {}
@@ -10,6 +10,37 @@ error[E0053]: method `test` has an incompatible type for trait
= note: expected type `fn(u64)`
found type `fn(std::string::String)`
error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait
--> $DIR/impl_incorrect_method_signature.rs:18:1
|
12 | / decl_runtime_apis! {
13 | | pub trait Api {
14 | | fn test(data: u64);
15 | | }
16 | | }
| |_- type in trait
17 |
18 | impl_runtime_apis! {
| ^^^^^^^^^^^^^^^^^^ expected u64, found struct `std::string::String`
|
= note: expected type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
found type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<std::string::String>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
error[E0308]: mismatched types
--> $DIR/impl_incorrect_method_signature.rs:18:1
|
18 | / impl_runtime_apis! {
19 | | impl self::Api<Block> for Runtime {
20 | | fn test(data: String) {}
21 | | }
... |
33 | | }
34 | | }
| |_^ expected u64, found struct `std::string::String`
|
= note: expected type `u64`
found type `std::string::String`
error[E0308]: mismatched types
--> $DIR/impl_incorrect_method_signature.rs:20:11
|
@@ -18,6 +49,3 @@ error[E0308]: mismatched types
|
= note: expected type `u64`
found type `std::string::String`
Some errors have detailed explanations: E0053, E0308.
For more information about an error, try `rustc --explain E0053`.
@@ -16,6 +16,8 @@ decl_runtime_apis! {
}
mod second {
use super::*;
decl_runtime_apis! {
pub trait Api {
fn test2(data: u64);
@@ -1,25 +1,17 @@
error: Two traits with the same name detected! The trait name is used to generate its ID. Please rename one trait at the declaration!
--> $DIR/impl_two_traits_with_same_name.rs:31:15
--> $DIR/impl_two_traits_with_same_name.rs:33:15
|
31 | impl second::Api<Block> for Runtime {
33 | impl second::Api<Block> for Runtime {
| ^^^
error: cannot find macro `decl_runtime_apis!` in this scope
--> $DIR/impl_two_traits_with_same_name.rs:19:2
error[E0277]: the trait bound `RuntimeApiImpl<RuntimeApiImplCall>: sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not satisfied
--> $DIR/impl_two_traits_with_same_name.rs:29:7
|
19 | decl_runtime_apis! {
| ^^^^^^^^^^^^^^^^^
29 | impl self::Api<Block> for Runtime {
| ^^^^^^^^^^^^^^^^ the trait `sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not implemented for `RuntimeApiImpl<RuntimeApiImplCall>`
error[E0433]: failed to resolve: could not find `runtime_decl_for_Api` in `second`
--> $DIR/impl_two_traits_with_same_name.rs:26:1
error[E0277]: the trait bound `RuntimeApiImpl<RuntimeApiImplCall>: sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not satisfied
--> $DIR/impl_two_traits_with_same_name.rs:33:7
|
26 | / impl_runtime_apis! {
27 | | impl self::Api<Block> for Runtime {
28 | | fn test(data: u64) {}
29 | | }
... |
33 | | }
34 | | }
| |_^ could not find `runtime_decl_for_Api` in `second`
For more information about this error, try `rustc --explain E0433`.
33 | impl second::Api<Block> for Runtime {
| ^^^^^^^^^^^^^^^^^^ the trait `sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not implemented for `RuntimeApiImpl<RuntimeApiImplCall>`
@@ -1,6 +1,6 @@
use sr_primitives::traits::GetNodeBlockType;
use sr_primitives::traits::{GetNodeBlockType, Block as BlockT};
use test_client::runtime::Block;
use client::{decl_runtime_apis, impl_runtime_apis};
use client::{decl_runtime_apis, impl_runtime_apis, runtime_api};
/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
/// trait are done by the `construct_runtime!` macro in a real runtime.
@@ -21,6 +21,18 @@ impl_runtime_apis! {
unimplemented!()
}
}
impl runtime_api::Core<Block> for Runtime {
fn version() -> runtime_api::RuntimeVersion {
unimplemented!()
}
fn execute_block(_: Block) {
unimplemented!()
}
fn initialize_block(_: &<Block as BlockT>::Header) {
unimplemented!()
}
}
}
fn main() {}
@@ -10,6 +10,22 @@ error[E0053]: method `test` has an incompatible type for trait
= note: expected type `fn(u64)`
found type `fn(&u64)`
error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait
--> $DIR/type_reference_in_impl_runtime_apis_call.rs:18:1
|
12 | / decl_runtime_apis! {
13 | | pub trait Api {
14 | | fn test(data: u64);
15 | | }
16 | | }
| |_- type in trait
17 |
18 | impl_runtime_apis! {
| ^^^^^^^^^^^^^^^^^^ expected u64, found &u64
|
= note: expected type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
found type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
error[E0308]: mismatched types
--> $DIR/type_reference_in_impl_runtime_apis_call.rs:18:1
|
@@ -17,13 +33,10 @@ error[E0308]: mismatched types
19 | | impl self::Api<Block> for Runtime {
20 | | fn test(data: &u64) {
21 | | unimplemented!()
22 | | }
23 | | }
24 | | }
... |
35 | | }
36 | | }
| |_^ expected u64, found &u64
|
= note: expected type `u64`
found type `&u64`
Some errors have detailed explanations: E0053, E0308.
For more information about an error, try `rustc --explain E0053`.