5
5
6
6
use std:: { marker:: Unpin , sync:: LazyLock } ;
7
7
8
- use bytes:: Bytes ;
9
8
use linera_base:: data_types:: Bytecode ;
10
9
use linera_witty:: {
11
10
wasmer:: { EntrypointInstance , InstanceBuilder } ,
12
11
ExportTo ,
13
12
} ;
14
13
use tokio:: sync:: Mutex ;
15
14
use wasm_instrument:: { gas_metering, parity_wasm} ;
16
- use wasmer:: { Engine , Module , Store } ;
17
15
18
16
use super :: {
19
17
module_cache:: ModuleCache ,
@@ -27,7 +25,7 @@ use crate::{
27
25
} ;
28
26
29
27
/// An [`Engine`] instance configured to run application services.
30
- static SERVICE_ENGINE : LazyLock < Engine > = LazyLock :: new ( || {
28
+ static SERVICE_ENGINE : LazyLock < wasmer :: Engine > = LazyLock :: new ( || {
31
29
#[ cfg( web) ]
32
30
{
33
31
wasmer:: Engine :: default ( )
@@ -39,12 +37,12 @@ static SERVICE_ENGINE: LazyLock<Engine> = LazyLock::new(|| {
39
37
}
40
38
} ) ;
41
39
42
- /// A cache of compiled contract modules, with their respective [`Engine`] instances.
40
+ /// A cache of compiled contract modules, with their respective [`wasmer:: Engine`] instances.
43
41
static CONTRACT_CACHE : LazyLock < Mutex < ModuleCache < CachedContractModule > > > =
44
42
LazyLock :: new ( Mutex :: default) ;
45
43
46
44
/// A cache of compiled service modules.
47
- static SERVICE_CACHE : LazyLock < Mutex < ModuleCache < Module > > > = LazyLock :: new ( Mutex :: default) ;
45
+ static SERVICE_CACHE : LazyLock < Mutex < ModuleCache < wasmer :: Module > > > = LazyLock :: new ( Mutex :: default) ;
48
46
49
47
/// Type representing a running [Wasmer](https://wasmer.io/) contract.
50
48
pub ( crate ) struct WasmerContractInstance < Runtime > {
77
75
{
78
76
/// Prepares a runtime instance to call into the Wasm contract.
79
77
pub fn prepare (
80
- contract_engine : Engine ,
81
- contract_module : & Module ,
78
+ contract_engine : wasmer :: Engine ,
79
+ contract_module : & wasmer :: Module ,
82
80
runtime : Runtime ,
83
81
) -> Result < Self , WasmExecutionError > {
84
82
let system_api_data = SystemApiData :: new ( runtime) ;
@@ -99,7 +97,7 @@ impl WasmServiceModule {
99
97
let mut service_cache = SERVICE_CACHE . lock ( ) . await ;
100
98
let module = service_cache
101
99
. get_or_insert_with ( service_bytecode, |bytecode| {
102
- Module :: new ( & * SERVICE_ENGINE , bytecode) . map_err ( anyhow:: Error :: from)
100
+ wasmer :: Module :: new ( & * SERVICE_ENGINE , bytecode) . map_err ( anyhow:: Error :: from)
103
101
} )
104
102
. map_err ( WasmExecutionError :: LoadServiceModule ) ?;
105
103
Ok ( WasmServiceModule :: Wasmer { module } )
@@ -111,7 +109,10 @@ where
111
109
Runtime : ServiceRuntime + WriteBatch + Clone + Unpin + ' static ,
112
110
{
113
111
/// Prepares a runtime instance to call into the Wasm service.
114
- pub fn prepare ( service_module : & Module , runtime : Runtime ) -> Result < Self , WasmExecutionError > {
112
+ pub fn prepare (
113
+ service_module : & wasmer:: Module ,
114
+ runtime : Runtime ,
115
+ ) -> Result < Self , WasmExecutionError > {
115
116
let system_api_data = SystemApiData :: new ( runtime) ;
116
117
let mut instance_builder = InstanceBuilder :: new ( SERVICE_ENGINE . clone ( ) , system_api_data) ;
117
118
@@ -197,9 +198,9 @@ impl From<wasmer::RuntimeError> for ExecutionError {
197
198
}
198
199
199
200
/// Serialized bytes of a compiled contract bytecode.
200
- pub struct CachedContractModule {
201
- compiled_bytecode : Bytes ,
202
- }
201
+ // Cloning `Module`s is cheap.
202
+ # [ derive ( Clone ) ]
203
+ pub struct CachedContractModule ( wasmer :: Module ) ;
203
204
204
205
pub fn add_metering ( bytecode : Bytecode ) -> anyhow:: Result < Bytecode > {
205
206
struct WasmtimeRules ;
@@ -246,16 +247,15 @@ pub fn add_metering(bytecode: Bytecode) -> anyhow::Result<Bytecode> {
246
247
impl CachedContractModule {
247
248
/// Creates a new [`CachedContractModule`] by compiling a `contract_bytecode`.
248
249
pub fn new ( contract_bytecode : Bytecode ) -> Result < Self , anyhow:: Error > {
249
- let module = Module :: new (
250
+ let module = wasmer :: Module :: new (
250
251
& Self :: create_compilation_engine ( ) ,
251
252
add_metering ( contract_bytecode) ?,
252
253
) ?;
253
- let compiled_bytecode = module. serialize ( ) ?;
254
- Ok ( CachedContractModule { compiled_bytecode } )
254
+ Ok ( CachedContractModule ( module) )
255
255
}
256
256
257
257
/// Creates a new [`Engine`] to compile a contract bytecode.
258
- fn create_compilation_engine ( ) -> Engine {
258
+ fn create_compilation_engine ( ) -> wasmer :: Engine {
259
259
#[ cfg( not( web) ) ]
260
260
{
261
261
let mut compiler_config = wasmer_compiler_singlepass:: Singlepass :: default ( ) ;
@@ -269,10 +269,21 @@ impl CachedContractModule {
269
269
}
270
270
271
271
/// Creates a [`Module`] from a compiled contract using a headless [`Engine`].
272
- pub fn create_execution_instance ( & self ) -> Result < ( Engine , Module ) , anyhow:: Error > {
273
- let engine = Engine :: default ( ) ;
274
- let store = Store :: new ( engine. clone ( ) ) ;
275
- let module = unsafe { Module :: deserialize ( & store, & * self . compiled_bytecode ) } ?;
276
- Ok ( ( engine, module) )
272
+ pub fn create_execution_instance (
273
+ & self ,
274
+ ) -> Result < ( wasmer:: Engine , wasmer:: Module ) , anyhow:: Error > {
275
+ #[ cfg( web) ]
276
+ {
277
+ Ok ( ( wasmer:: Engine :: default ( ) , self . 0 . clone ( ) ) )
278
+ }
279
+
280
+ #[ cfg( not( web) ) ]
281
+ {
282
+ let engine = wasmer:: Engine :: default ( ) ;
283
+ let store = wasmer:: Store :: new ( engine. clone ( ) ) ;
284
+ let bytes = self . 0 . serialize ( ) ?;
285
+ let module = unsafe { wasmer:: Module :: deserialize ( & store, bytes) } ?;
286
+ Ok ( ( engine, module) )
287
+ }
277
288
}
278
289
}
0 commit comments