Skip to main content

sp_runtime_interface/
impls.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Provides implementations for the runtime interface types which can be
19//! passed directly without any serialization strategy wrappers.
20
21#[cfg(not(substrate_runtime))]
22use crate::host::*;
23#[cfg(substrate_runtime)]
24use crate::wasm::*;
25use crate::{Pointer, RIType};
26
27#[cfg(not(substrate_runtime))]
28use sp_wasm_interface::{FunctionContext, Result};
29
30// On riscv64, usize is 8 bytes, so these assertions only hold for 32-bit targets.
31#[cfg(all(
32	substrate_runtime,
33	not(feature = "disable_target_static_assertions"),
34	not(target_arch = "riscv64")
35))]
36const _: () = {
37	assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u32>());
38	assert!(core::mem::size_of::<*const u8>() == core::mem::size_of::<u32>());
39};
40
41/// Implement the traits for the given primitive traits.
42macro_rules! impl_traits_for_primitives {
43	(
44		$(
45			$rty:ty, $fty:ty,
46		)*
47	) => {
48		$(
49			/// The type is passed directly.
50			impl RIType for $rty {
51				type FFIType = $fty;
52				type Inner = Self;
53			}
54
55			#[cfg(substrate_runtime)]
56			impl IntoFFIValue for $rty {
57				type Destructor = ();
58
59				fn into_ffi_value(value: &mut $rty) -> (Self::FFIType, Self::Destructor) {
60					(*value as $fty, ())
61				}
62			}
63
64			#[cfg(substrate_runtime)]
65			impl FromFFIValue for $rty {
66				fn from_ffi_value(arg: $fty) -> $rty {
67					arg as $rty
68				}
69			}
70
71			#[cfg(not(substrate_runtime))]
72			impl<'a> FromFFIValue<'a> for $rty {
73				type Owned = Self;
74
75				fn from_ffi_value(_: &mut dyn FunctionContext, arg: $fty) -> Result<$rty> {
76					Ok(arg as $rty)
77				}
78
79				fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
80					*owned
81				}
82			}
83
84			#[cfg(not(substrate_runtime))]
85			impl IntoFFIValue for $rty {
86				fn into_ffi_value(value: Self::Inner, _: &mut dyn FunctionContext) -> Result<$fty> {
87					Ok(value as $fty)
88				}
89			}
90		)*
91	}
92}
93
94impl_traits_for_primitives! {
95	u8, u32,
96	u16, u32,
97	u32, u32,
98	u64, u64,
99	i8, i32,
100	i16, i32,
101	i32, i32,
102	i64, i64,
103}
104
105/// `bool` is passed as `u32`.
106///
107/// - `1`: true
108/// - `0`: false
109impl RIType for bool {
110	type FFIType = u32;
111	type Inner = Self;
112}
113
114#[cfg(substrate_runtime)]
115impl IntoFFIValue for bool {
116	type Destructor = ();
117
118	fn into_ffi_value(value: &mut bool) -> (Self::FFIType, Self::Destructor) {
119		(if *value { 1 } else { 0 }, ())
120	}
121}
122
123#[cfg(substrate_runtime)]
124impl FromFFIValue for bool {
125	fn from_ffi_value(arg: u32) -> bool {
126		arg == 1
127	}
128}
129
130#[cfg(not(substrate_runtime))]
131impl<'a> FromFFIValue<'a> for bool {
132	type Owned = Self;
133
134	fn from_ffi_value(_: &mut dyn FunctionContext, arg: u32) -> Result<bool> {
135		Ok(arg == 1)
136	}
137
138	fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
139		*owned
140	}
141}
142
143#[cfg(not(substrate_runtime))]
144impl IntoFFIValue for bool {
145	fn into_ffi_value(value: Self, _: &mut dyn FunctionContext) -> Result<u32> {
146		Ok(if value { 1 } else { 0 })
147	}
148}
149
150#[cfg(not(substrate_runtime))]
151impl<T: sp_wasm_interface::PointerType> RIType for Pointer<T> {
152	type FFIType = u32;
153	type Inner = Self;
154}
155
156/// The type is passed as `u32`.
157#[cfg(substrate_runtime)]
158impl<T> RIType for Pointer<T> {
159	type FFIType = u32;
160	type Inner = Self;
161}
162
163#[cfg(substrate_runtime)]
164impl<T> IntoFFIValue for Pointer<T> {
165	type Destructor = ();
166
167	fn into_ffi_value(value: &mut Pointer<T>) -> (Self::FFIType, Self::Destructor) {
168		(*value as u32, ())
169	}
170}
171
172#[cfg(substrate_runtime)]
173impl<T> FromFFIValue for Pointer<T> {
174	fn from_ffi_value(arg: u32) -> Self {
175		arg as _
176	}
177}
178
179#[cfg(not(substrate_runtime))]
180impl<'a, T: sp_wasm_interface::PointerType> FromFFIValue<'a> for Pointer<T> {
181	type Owned = Self;
182
183	fn from_ffi_value(_: &mut dyn FunctionContext, arg: u32) -> Result<Self> {
184		Ok(Pointer::new(arg))
185	}
186
187	fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
188		*owned
189	}
190}
191
192#[cfg(not(substrate_runtime))]
193impl<T: sp_wasm_interface::PointerType> IntoFFIValue for Pointer<T> {
194	fn into_ffi_value(value: Self, _: &mut dyn FunctionContext) -> Result<u32> {
195		Ok(value.into())
196	}
197}