@@ -10,6 +10,7 @@ use std::{
10
10
path:: PathBuf ,
11
11
process:: { Command , Stdio } ,
12
12
str:: FromStr ,
13
+ sync:: Mutex ,
13
14
} ;
14
15
15
16
struct Cache {
@@ -201,16 +202,17 @@ struct SourceLocation {
201
202
202
203
#[ derive( Default ) ]
203
204
pub struct Compiler {
204
- cache : Option < Cache > ,
205
+ cache : Option < Mutex < Cache > > ,
205
206
compile : bool ,
206
207
}
207
208
208
209
impl Compiler {
209
210
pub fn new ( compile : bool , cache_path : Option < PathBuf > ) -> Result < Self > {
210
- let cache = cache_path. map ( Cache :: new) . transpose ( ) ?;
211
+ let cache = cache_path. map ( Cache :: new) . transpose ( ) ?. map ( Mutex :: new ) ;
211
212
Ok ( Compiler { compile, cache } )
212
213
}
213
214
215
+ /// the concurrency level of the exec is controlled by rayon parallelism
214
216
fn exec ( args : & [ & str ] , stdin : & str ) -> Result < String > {
215
217
let mut child = Command :: new ( "docker" )
216
218
. args ( args)
@@ -242,7 +244,7 @@ impl Compiler {
242
244
}
243
245
244
246
/// compiles ASM code
245
- pub fn asm ( & mut self , src : & str ) -> Result < Bytes > {
247
+ pub fn asm ( & self , src : & str ) -> Result < Bytes > {
246
248
let mut bytecode = Bytecode :: default ( ) ;
247
249
for op in src. split ( ';' ) {
248
250
let op = match bytecode:: OpcodeWithData :: from_str ( op. trim ( ) ) {
@@ -256,9 +258,13 @@ impl Compiler {
256
258
}
257
259
258
260
/// compiles LLL code
259
- pub fn lll ( & mut self , src : & str ) -> Result < Bytes > {
260
- if let Some ( bytecode) = self . cache . as_mut ( ) . and_then ( |c| c. get ( src) ) {
261
- return Ok ( bytecode. clone ( ) ) ;
261
+ pub fn lll ( & self , src : & str ) -> Result < Bytes > {
262
+ if let Some ( bytecode) = self
263
+ . cache
264
+ . as_ref ( )
265
+ . and_then ( |c| c. lock ( ) . unwrap ( ) . get ( src) . cloned ( ) )
266
+ {
267
+ return Ok ( bytecode) ;
262
268
}
263
269
if !self . compile {
264
270
bail ! ( "No way to compile LLLC for '{}'" , src)
@@ -267,26 +273,30 @@ impl Compiler {
267
273
let stdout = Self :: exec ( & [ "run" , "-i" , "--rm" , "lllc" ] , src) ?;
268
274
let bytecode = Bytes :: from ( hex:: decode ( stdout. trim ( ) ) ?) ;
269
275
270
- if let Some ( cache) = & mut self . cache {
271
- cache. insert ( src, bytecode. clone ( ) ) ?;
276
+ if let Some ( ref cache) = self . cache {
277
+ cache. lock ( ) . unwrap ( ) . insert ( src, bytecode. clone ( ) ) ?;
272
278
}
273
279
274
280
Ok ( bytecode)
275
281
}
276
282
277
283
/// compiles YUL code
278
- pub fn yul ( & mut self , src : & str ) -> Result < Bytes > {
284
+ pub fn yul ( & self , src : & str ) -> Result < Bytes > {
279
285
self . solc ( Language :: Yul , src)
280
286
}
281
287
282
288
/// compiles Solidity code
283
- pub fn solidity ( & mut self , src : & str ) -> Result < Bytes > {
289
+ pub fn solidity ( & self , src : & str ) -> Result < Bytes > {
284
290
self . solc ( Language :: Solidity , src)
285
291
}
286
292
287
- fn solc ( & mut self , language : Language , src : & str ) -> Result < Bytes > {
288
- if let Some ( bytecode) = self . cache . as_mut ( ) . and_then ( |c| c. get ( src) ) {
289
- return Ok ( bytecode. clone ( ) ) ;
293
+ fn solc ( & self , language : Language , src : & str ) -> Result < Bytes > {
294
+ if let Some ( bytecode) = self
295
+ . cache
296
+ . as_ref ( )
297
+ . and_then ( |c| c. lock ( ) . unwrap ( ) . get ( src) . cloned ( ) )
298
+ {
299
+ return Ok ( bytecode) ;
290
300
}
291
301
if !self . compile {
292
302
bail ! ( "No way to compile {:?} for '{}'" , language, src)
@@ -312,8 +322,8 @@ impl Compiler {
312
322
313
323
let bytecode = Bytes :: from ( hex:: decode ( bytecode) ?) ;
314
324
315
- if let Some ( cache) = & mut self . cache {
316
- cache. insert ( src, bytecode. clone ( ) ) ?;
325
+ if let Some ( ref cache) = self . cache {
326
+ cache. lock ( ) . unwrap ( ) . insert ( src, bytecode. clone ( ) ) ?;
317
327
}
318
328
319
329
Ok ( bytecode)
0 commit comments