@@ -13,12 +13,17 @@ use std::{
13
13
any:: Any ,
14
14
ffi:: { c_void, CString } ,
15
15
mem,
16
+ ops:: Deref ,
16
17
ptr:: { self , NonNull } ,
17
18
slice, str,
18
- sync:: Once ,
19
+ sync:: { Arc , Once } ,
19
20
} ;
20
21
use wasmer_runtime_core:: {
21
- backend:: RunnableModule ,
22
+ backend:: {
23
+ sys:: { Memory , Protect } ,
24
+ CacheGen , RunnableModule ,
25
+ } ,
26
+ cache:: Error as CacheError ,
22
27
module:: ModuleInfo ,
23
28
structures:: TypedIndex ,
24
29
typed_func:: { Wasm , WasmTrapInfo } ,
@@ -203,17 +208,32 @@ fn get_callbacks() -> Callbacks {
203
208
}
204
209
}
205
210
211
+ pub enum Buffer {
212
+ LlvmMemory ( MemoryBuffer ) ,
213
+ Memory ( Memory ) ,
214
+ }
215
+
216
+ impl Deref for Buffer {
217
+ type Target = [ u8 ] ;
218
+ fn deref ( & self ) -> & [ u8 ] {
219
+ match self {
220
+ Buffer :: LlvmMemory ( mem_buffer) => mem_buffer. as_slice ( ) ,
221
+ Buffer :: Memory ( memory) => unsafe { memory. as_slice ( ) } ,
222
+ }
223
+ }
224
+ }
225
+
206
226
unsafe impl Send for LLVMBackend { }
207
227
unsafe impl Sync for LLVMBackend { }
208
228
209
229
pub struct LLVMBackend {
210
230
module : * mut LLVMModule ,
211
231
#[ allow( dead_code) ]
212
- memory_buffer : MemoryBuffer ,
232
+ buffer : Arc < Buffer > ,
213
233
}
214
234
215
235
impl LLVMBackend {
216
- pub fn new ( module : Module , _intrinsics : Intrinsics ) -> Self {
236
+ pub fn new ( module : Module , _intrinsics : Intrinsics ) -> ( Self , LLVMCache ) {
217
237
Target :: initialize_x86 ( & InitializationConfig {
218
238
asm_parser : true ,
219
239
asm_printer : true ,
@@ -262,10 +282,44 @@ impl LLVMBackend {
262
282
panic ! ( "failed to load object" )
263
283
}
264
284
265
- Self {
266
- module,
267
- memory_buffer,
285
+ let buffer = Arc :: new ( Buffer :: LlvmMemory ( memory_buffer) ) ;
286
+
287
+ (
288
+ Self {
289
+ module,
290
+ buffer : Arc :: clone ( & buffer) ,
291
+ } ,
292
+ LLVMCache { buffer } ,
293
+ )
294
+ }
295
+
296
+ pub unsafe fn from_buffer ( memory : Memory ) -> Result < ( Self , LLVMCache ) , String > {
297
+ let callbacks = get_callbacks ( ) ;
298
+ let mut module: * mut LLVMModule = ptr:: null_mut ( ) ;
299
+
300
+ let slice = unsafe { memory. as_slice ( ) } ;
301
+
302
+ let res = module_load ( slice. as_ptr ( ) , slice. len ( ) , callbacks, & mut module) ;
303
+
304
+ if res != LLVMResult :: OK {
305
+ return Err ( "failed to load object" . to_string ( ) ) ;
268
306
}
307
+
308
+ static SIGNAL_HANDLER_INSTALLED : Once = Once :: new ( ) ;
309
+
310
+ SIGNAL_HANDLER_INSTALLED . call_once ( || unsafe {
311
+ crate :: platform:: install_signal_handler ( ) ;
312
+ } ) ;
313
+
314
+ let buffer = Arc :: new ( Buffer :: Memory ( memory) ) ;
315
+
316
+ Ok ( (
317
+ Self {
318
+ module,
319
+ buffer : Arc :: clone ( & buffer) ,
320
+ } ,
321
+ LLVMCache { buffer } ,
322
+ ) )
269
323
}
270
324
}
271
325
@@ -322,6 +376,28 @@ impl RunnableModule for LLVMBackend {
322
376
}
323
377
}
324
378
379
+ unsafe impl Send for LLVMCache { }
380
+ unsafe impl Sync for LLVMCache { }
381
+
382
+ pub struct LLVMCache {
383
+ buffer : Arc < Buffer > ,
384
+ }
385
+
386
+ impl CacheGen for LLVMCache {
387
+ fn generate_cache ( & self ) -> Result < ( Box < [ u8 ] > , Memory ) , CacheError > {
388
+ let mut memory = Memory :: with_size_protect ( self . buffer . len ( ) , Protect :: ReadWrite )
389
+ . map_err ( CacheError :: SerializeError ) ?;
390
+
391
+ let buffer = self . buffer . deref ( ) ;
392
+
393
+ unsafe {
394
+ memory. as_slice_mut ( ) [ ..buffer. len ( ) ] . copy_from_slice ( buffer) ;
395
+ }
396
+
397
+ Ok ( ( [ ] . as_ref ( ) . into ( ) , memory) )
398
+ }
399
+ }
400
+
325
401
#[ cfg( feature = "disasm" ) ]
326
402
unsafe fn disass_ptr ( ptr : * const u8 , size : usize , inst_count : usize ) {
327
403
use capstone:: arch:: BuildsCapstone ;
0 commit comments