Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit f7a02fc

Browse files
committed
more refactor
1 parent b001b81 commit f7a02fc

4 files changed

Lines changed: 75 additions & 48 deletions

File tree

client/executor/src/native_executor.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ use crate::{
2020
RuntimeInfo, error::{Error, Result},
2121
wasm_runtime::{RuntimeCache, WasmExecutionMethod},
2222
};
23+
24+
use std::{
25+
collections::HashMap,
26+
panic::{UnwindSafe, AssertUnwindSafe},
27+
result,
28+
sync::{Arc, atomic::{AtomicU64, Ordering}, mpsc},
29+
};
30+
2331
use sp_version::{NativeVersion, RuntimeVersion};
2432
use codec::{Decode, Encode};
2533
use sp_core::{
26-
NativeOrEncoded, traits::{CodeExecutor, Externalities, RuntimeCode, MissingHostFunctions},
34+
NativeOrEncoded,
35+
traits::{
36+
CodeExecutor, Externalities, RuntimeCode, MissingHostFunctions,
37+
},
2738
};
2839
use log::trace;
29-
use std::{result, panic::{UnwindSafe, AssertUnwindSafe}, sync::Arc, collections::HashMap};
3040
use sp_wasm_interface::{HostFunctions, Function};
3141
use sc_executor_common::wasm_runtime::{WasmInstance, WasmModule, CallSite};
3242
use sp_externalities::ExternalitiesExt as _;
@@ -288,16 +298,16 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
288298

289299
pub struct RuntimeInstanceSpawn {
290300
module: Arc<dyn WasmModule>,
291-
forks: parking_lot::Mutex<HashMap<u32, std::sync::mpsc::Receiver<Vec<u8>>>>,
292-
counter: std::sync::atomic::AtomicU32,
301+
forks: parking_lot::Mutex<HashMap<u64, mpsc::Receiver<Vec<u8>>>>,
302+
counter: AtomicU64,
293303
scheduler: Box<dyn sp_core::traits::SpawnNamed>,
294304
}
295305

296306
impl sp_io::RuntimeSpawn for RuntimeInstanceSpawn {
297-
fn dyn_dispatch(&self, dispatcher_ref: u32, func: u32, data: Vec<u8>) -> u32 {
298-
let new_handle = self.counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
307+
fn dyn_dispatch(&self, dispatcher_ref: u32, func: u32, data: Vec<u8>) -> u64 {
308+
let new_handle = self.counter.fetch_add(1, Ordering::Relaxed);
299309

300-
let (sender, receiver) = std::sync::mpsc::channel();
310+
let (sender, receiver) = mpsc::channel();
301311
self.forks.lock().insert(new_handle, receiver);
302312

303313
let module = self.module.clone();
@@ -312,7 +322,7 @@ impl sp_io::RuntimeSpawn for RuntimeInstanceSpawn {
312322
move || {
313323

314324
// FIXME: Should be refactored to shared "instance factory".
315-
// Instatiating wasm here every time is suboptimal at the moment, shared
325+
// Instantiating wasm here every time is suboptimal at the moment, shared
316326
// pool of istances should be used.
317327
let instance = module.new_instance().expect("Failed to create new instance for fork");
318328

@@ -324,7 +334,7 @@ impl sp_io::RuntimeSpawn for RuntimeInstanceSpawn {
324334
);
325335

326336
// If execution is panicked, the `join` in the original runtime code will panic as well,
327-
// since the snder is dropped without seding anything.
337+
// since the sender is dropped without seding anything.
328338
if let Ok(output) = result {
329339
let _ = sender.send(output);
330340
}
@@ -334,7 +344,7 @@ impl sp_io::RuntimeSpawn for RuntimeInstanceSpawn {
334344
new_handle
335345
}
336346

337-
fn join(&self, handle: u32) -> Vec<u8> {
347+
fn join(&self, handle: u64) -> Vec<u8> {
338348
let receiver = self.forks.lock().remove(&handle).expect("No fork for such handle");
339349
let output = receiver.recv().expect("No signal from forked execution");
340350
output

client/executor/wasmtime/src/instance_wrapper.rs

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub struct EntryPoint {
8888
}
8989

9090
impl EntryPoint {
91+
/// Call this entry point.
9192
pub fn call(&self, data_ptr: Pointer<u8>, data_len: WordSize) -> anyhow::Result<u64> {
9293
let data_ptr = u32::from(data_ptr) as i32;
9394
let data_len = u32::from(data_len) as i32;
@@ -108,6 +109,31 @@ impl EntryPoint {
108109
},
109110
}).map(|results| results[0].unwrap_i64() as u64)
110111
}
112+
113+
pub fn direct(func: wasmtime::Func) -> std::result::Result<Self, &'static str> {
114+
match (func.ty().params(), func.ty().results()) {
115+
(&[wasmtime::ValType::I32, wasmtime::ValType::I32], &[wasmtime::ValType::I64]) => {
116+
Ok(Self { func, call_type: EntryPointType::Direct })
117+
}
118+
_ => {
119+
Err("Invalid signature")
120+
}
121+
}
122+
}
123+
124+
pub fn wrapped(dispatcher: wasmtime::Func, func: u32) -> std::result::Result<Self, &'static str> {
125+
match (dispatcher.ty().params(), dispatcher.ty().results()) {
126+
(
127+
&[wasmtime::ValType::I32, wasmtime::ValType::I32, wasmtime::ValType::I32],
128+
&[wasmtime::ValType::I64],
129+
) => {
130+
Ok(Self { func: dispatcher, call_type: EntryPointType::Wrapped(func) })
131+
},
132+
_ => {
133+
Err("Invalid signature")
134+
}
135+
}
136+
}
111137
}
112138

113139
/// Wrap the given WebAssembly Instance of a wasm module with Substrate-runtime.
@@ -199,16 +225,13 @@ impl InstanceWrapper {
199225
let func = extern_func(&export)
200226
.ok_or_else(|| Error::from(format!("Export {} is not a function", method)))?
201227
.clone();
202-
match (func.ty().params(), func.ty().results()) {
203-
(&[wasmtime::ValType::I32, wasmtime::ValType::I32], &[wasmtime::ValType::I64]) => {}
204-
_ => {
205-
return Err(Error::from(format!(
206-
"method {} have an unsupported signature",
228+
EntryPoint::direct(func)
229+
.map_err(|_|
230+
Error::from(format!(
231+
"Function '{}' has invalid signature.",
207232
method,
208-
)))
209-
}
210-
}
211-
EntryPoint { call_type: EntryPointType::Direct, func }
233+
))
234+
)?
212235
},
213236
CallSite::Table(func_ref) => {
214237
let table = self.instance.get_table("__indirect_function_table").ok_or(Error::NoTable)?;
@@ -220,39 +243,31 @@ impl InstanceWrapper {
220243
.ok_or(Error::FunctionRefIsNull(func_ref))?
221244
.clone();
222245

223-
match (func.ty().params(), func.ty().results()) {
224-
(&[wasmtime::ValType::I32, wasmtime::ValType::I32], &[wasmtime::ValType::I64]) => {}
225-
_ => {
226-
return Err(Error::from(format!(
227-
"Function @{} have an unsupported signature",
246+
EntryPoint::direct(func)
247+
.map_err(|_|
248+
Error::from(format!(
249+
"Function @{} has invalid signature.",
228250
func_ref,
229-
)))
230-
}
231-
}
232-
EntryPoint { call_type: EntryPointType::Direct, func }
233-
},
251+
))
252+
)?
253+
},
234254
CallSite::TableWithWrapper { dispatcher_ref, func } => {
235255
let table = self.instance.get_table("__indirect_function_table").ok_or(Error::NoTable)?;
236256
let val = table.get(dispatcher_ref)
237257
.ok_or(Error::NoTableEntryWithIndex(dispatcher_ref))?;
238258
let dispatcher = val
239259
.funcref()
240260
.ok_or(Error::TableElementIsNotAFunction(dispatcher_ref))?
241-
.ok_or(Error::FunctionRefIsNull(dispatcher_ref))?;
242-
243-
match (dispatcher.ty().params(), dispatcher.ty().results()) {
244-
(
245-
&[wasmtime::ValType::I32, wasmtime::ValType::I32, wasmtime::ValType::I32],
246-
&[wasmtime::ValType::I64],
247-
) => {},
248-
_ => {
249-
return Err(Error::from(format!(
250-
"Function @{} have an unsupported signature",
261+
.ok_or(Error::FunctionRefIsNull(dispatcher_ref))?
262+
.clone();
263+
264+
EntryPoint::wrapped(dispatcher, func)
265+
.map_err(|_|
266+
Error::from(format!(
267+
"Function @{} has invalid signature.",
251268
dispatcher_ref,
252-
)))
253-
}
254-
}
255-
EntryPoint { call_type: EntryPointType::Wrapped(func), func: dispatcher.clone() }
269+
))
270+
)?
256271
},
257272
})
258273
}

primitives/io/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,10 +1151,12 @@ pub trait Sandbox {
11511151
/// Runtime spawn extension.
11521152
pub trait RuntimeSpawn : Send {
11531153
/// Create new runtime instance and use dynamic dispatch to invoke with specified payload.
1154-
fn dyn_dispatch(&self, dispatcher_ref: u32, func: u32, payload: Vec<u8>) -> u32;
1154+
///
1155+
/// Returns handle of the spawned task.
1156+
fn dyn_dispatch(&self, dispatcher_ref: u32, func: u32, payload: Vec<u8>) -> u64;
11551157

11561158
/// Join the result of previously created runtime instance invocation.
1157-
fn join(&self, handle: u32) -> Vec<u8>;
1159+
fn join(&self, handle: u64) -> Vec<u8>;
11581160
}
11591161

11601162
#[cfg(feature = "std")]
@@ -1171,7 +1173,7 @@ pub trait RuntimeTasks {
11711173
/// Wasm host function for spawning task.
11721174
///
11731175
/// This should not be used directly. Use `sp_io::tasks::spawn` instead.
1174-
fn spawn(&mut self, dispatcher_ref: u32, entry: u32, payload: Vec<u8>) -> u32 {
1176+
fn spawn(&mut self, dispatcher_ref: u32, entry: u32, payload: Vec<u8>) -> u64 {
11751177
let runtime_spawn = self.extension::<RuntimeSpawnExt>()
11761178
.expect("Cannot spawn without dynamic runtime dispatcher (RuntimeSpawnExt)");
11771179
runtime_spawn.dyn_dispatch(dispatcher_ref, entry, payload)
@@ -1180,7 +1182,7 @@ pub trait RuntimeTasks {
11801182
/// Wasm host function for joining a task.
11811183
///
11821184
/// This should not be used directly. Use `join` of `sp_io::tasks::spawn` result instead.
1183-
fn join(&mut self, handle: u32) -> Vec<u8> {
1185+
fn join(&mut self, handle: u64) -> Vec<u8> {
11841186
let runtime_spawn = self.extension::<RuntimeSpawnExt>()
11851187
.expect("Cannot spawn without dynamic runtime dispatcher (RuntimeSpawnExt)");
11861188
runtime_spawn.join(handle)

primitives/io/src/tasks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ mod inner {
122122
/// This can be `join`-ed to get (blocking) the result of
123123
/// the spawned task execution.
124124
pub struct DataJoinHandle {
125-
handle: u32,
125+
handle: u64,
126126
}
127127

128128
impl DataJoinHandle {

0 commit comments

Comments
 (0)