referrerpolicy=no-referrer-when-downgrade

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// Make sure that our assumptions for storing a pointer + its size in `u64` is valid.
31#[cfg(all(substrate_runtime, not(feature = "disable_target_static_assertions")))]
32const _: () = {
33	assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u32>());
34	assert!(core::mem::size_of::<*const u8>() == core::mem::size_of::<u32>());
35};
36
37/// Implement the traits for the given primitive traits.
38macro_rules! impl_traits_for_primitives {
39	(
40		$(
41			$rty:ty, $fty:ty,
42		)*
43	) => {
44		$(
45			/// The type is passed directly.
46			impl RIType for $rty {
47				type FFIType = $fty;
48				type Inner = Self;
49			}
50
51			#[cfg(substrate_runtime)]
52			impl IntoFFIValue for $rty {
53				type Destructor = ();
54
55				fn into_ffi_value(value: &mut $rty) -> (Self::FFIType, Self::Destructor) {
56					(*value as $fty, ())
57				}
58			}
59
60			#[cfg(substrate_runtime)]
61			impl FromFFIValue for $rty {
62				fn from_ffi_value(arg: $fty) -> $rty {
63					arg as $rty
64				}
65			}
66
67			#[cfg(not(substrate_runtime))]
68			impl<'a> FromFFIValue<'a> for $rty {
69				type Owned = Self;
70
71				fn from_ffi_value(_: &mut dyn FunctionContext, arg: $fty) -> Result<$rty> {
72					Ok(arg as $rty)
73				}
74
75				fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
76					*owned
77				}
78			}
79
80			#[cfg(not(substrate_runtime))]
81			impl IntoFFIValue for $rty {
82				fn into_ffi_value(value: Self::Inner, _: &mut dyn FunctionContext) -> Result<$fty> {
83					Ok(value as $fty)
84				}
85			}
86		)*
87	}
88}
89
90impl_traits_for_primitives! {
91	u8, u32,
92	u16, u32,
93	u32, u32,
94	u64, u64,
95	i8, i32,
96	i16, i32,
97	i32, i32,
98	i64, i64,
99}
100
101/// `bool` is passed as `u32`.
102///
103/// - `1`: true
104/// - `0`: false
105impl RIType for bool {
106	type FFIType = u32;
107	type Inner = Self;
108}
109
110#[cfg(substrate_runtime)]
111impl IntoFFIValue for bool {
112	type Destructor = ();
113
114	fn into_ffi_value(value: &mut bool) -> (Self::FFIType, Self::Destructor) {
115		(if *value { 1 } else { 0 }, ())
116	}
117}
118
119#[cfg(substrate_runtime)]
120impl FromFFIValue for bool {
121	fn from_ffi_value(arg: u32) -> bool {
122		arg == 1
123	}
124}
125
126#[cfg(not(substrate_runtime))]
127impl<'a> FromFFIValue<'a> for bool {
128	type Owned = Self;
129
130	fn from_ffi_value(_: &mut dyn FunctionContext, arg: u32) -> Result<bool> {
131		Ok(arg == 1)
132	}
133
134	fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
135		*owned
136	}
137}
138
139#[cfg(not(substrate_runtime))]
140impl IntoFFIValue for bool {
141	fn into_ffi_value(value: Self, _: &mut dyn FunctionContext) -> Result<u32> {
142		Ok(if value { 1 } else { 0 })
143	}
144}
145
146#[cfg(not(substrate_runtime))]
147impl<T: sp_wasm_interface::PointerType> RIType for Pointer<T> {
148	type FFIType = u32;
149	type Inner = Self;
150}
151
152/// The type is passed as `u32`.
153#[cfg(substrate_runtime)]
154impl<T> RIType for Pointer<T> {
155	type FFIType = u32;
156	type Inner = Self;
157}
158
159#[cfg(substrate_runtime)]
160impl<T> IntoFFIValue for Pointer<T> {
161	type Destructor = ();
162
163	fn into_ffi_value(value: &mut Pointer<T>) -> (Self::FFIType, Self::Destructor) {
164		(*value as u32, ())
165	}
166}
167
168#[cfg(substrate_runtime)]
169impl<T> FromFFIValue for Pointer<T> {
170	fn from_ffi_value(arg: u32) -> Self {
171		arg as _
172	}
173}
174
175#[cfg(not(substrate_runtime))]
176impl<'a, T: sp_wasm_interface::PointerType> FromFFIValue<'a> for Pointer<T> {
177	type Owned = Self;
178
179	fn from_ffi_value(_: &mut dyn FunctionContext, arg: u32) -> Result<Self> {
180		Ok(Pointer::new(arg))
181	}
182
183	fn take_from_owned(owned: &'a mut Self::Owned) -> Self::Inner {
184		*owned
185	}
186}
187
188#[cfg(not(substrate_runtime))]
189impl<T: sp_wasm_interface::PointerType> IntoFFIValue for Pointer<T> {
190	fn into_ffi_value(value: Self, _: &mut dyn FunctionContext) -> Result<u32> {
191		Ok(value.into())
192	}
193}