1- use std:: sync:: atomic:: { AtomicBool , Ordering } ;
21use std:: time:: Instant ;
32
43use anyhow:: Error ;
@@ -262,10 +261,13 @@ impl WasmInstance {
262261 let host_fns = ctx. host_fns . cheap_clone ( ) ;
263262 let api_version = ctx. host_exports . data_source . api_version . clone ( ) ;
264263
264+ let gas = GasCounter :: new ( host_metrics. gas_metrics . clone ( ) ) ;
265+
265266 let wasm_ctx = WasmInstanceData :: from_instance (
266267 ctx,
267268 valid_module. cheap_clone ( ) ,
268269 host_metrics. cheap_clone ( ) ,
270+ gas. cheap_clone ( ) ,
269271 experimental_features,
270272 ) ;
271273 let mut store = Store :: new ( engine, wasm_ctx) ;
@@ -280,11 +282,6 @@ impl WasmInstance {
280282 // See also: runtime-timeouts
281283 store. set_epoch_deadline ( 2 ) ;
282284
283- // Because `gas` and `deterministic_host_trap` need to be accessed from the gas
284- // host fn, they need to be separate from the rest of the context.
285- let gas = GasCounter :: new ( host_metrics. gas_metrics . clone ( ) ) ;
286- let deterministic_host_trap = Arc :: new ( AtomicBool :: new ( false ) ) ;
287-
288285 // Helper to turn a parameter name into 'u32' for a tuple type
289286 // (param1, parma2, ..) : (u32, u32, ..)
290287 macro_rules! param_u32 {
@@ -313,14 +310,13 @@ impl WasmInstance {
313310
314311 // link an import with all the modules that require it.
315312 for module in modules {
316- let gas = gas. cheap_clone( ) ;
317313 linker. func_wrap_async(
318314 module,
319315 $wasm_name,
320316 move |mut caller: wasmtime:: Caller <' _, WasmInstanceData >,
321317 ( $( $param) ,* , ) : ( $( param_u32!( $param) ) ,* , ) | {
322- let gas = gas. cheap_clone( ) ;
323318 Box :: new( async move {
319+ let gas = caller. data( ) . gas. cheap_clone( ) ;
324320 let host_metrics = caller. data( ) . host_metrics. cheap_clone( ) ;
325321 let _section = host_metrics. stopwatch. start_section( $section) ;
326322
@@ -362,14 +358,13 @@ impl WasmInstance {
362358
363359 // link an import with all the modules that require it.
364360 for module in modules {
365- let gas = gas. cheap_clone( ) ;
366361 linker. func_wrap_async(
367362 module,
368363 $wasm_name,
369364 move |mut caller: wasmtime:: Caller <' _, WasmInstanceData >,
370365 _ : ( ) | {
371- let gas = gas. cheap_clone( ) ;
372366 Box :: new( async move {
367+ let gas = caller. data( ) . gas. cheap_clone( ) ;
373368 let host_metrics = caller. data( ) . host_metrics. cheap_clone( ) ;
374369 let _section = host_metrics. stopwatch. start_section( $section) ;
375370
@@ -409,17 +404,16 @@ impl WasmInstance {
409404
410405 for module in modules {
411406 let host_fn = host_fn. cheap_clone ( ) ;
412- let gas = gas. cheap_clone ( ) ;
413407 linker. func_wrap_async (
414408 module,
415409 host_fn. name ,
416410 move |mut caller : wasmtime:: Caller < ' _ , WasmInstanceData > ,
417411 ( call_ptr, ) : ( u32 , ) | {
418412 let host_fn = host_fn. cheap_clone ( ) ;
419- let gas = gas. cheap_clone ( ) ;
420413 Box :: new ( async move {
421414 let start = Instant :: now ( ) ;
422415
416+ let gas = caller. data ( ) . gas . cheap_clone ( ) ;
423417 let name_for_metrics = host_fn. name . replace ( '.' , "_" ) ;
424418 let host_metrics = caller. data ( ) . host_metrics . cheap_clone ( ) ;
425419 let stopwatch = host_metrics. stopwatch . cheap_clone ( ) ;
@@ -576,22 +570,28 @@ impl WasmInstance {
576570
577571 // link the `gas` function
578572 // See also e3f03e62-40e4-4f8c-b4a1-d0375cca0b76
579- {
580- let gas = gas. cheap_clone ( ) ;
581- linker. func_wrap ( "gas" , "gas" , move |gas_used : u32 | -> anyhow:: Result < ( ) > {
573+ linker. func_wrap (
574+ "gas" ,
575+ "gas" ,
576+ |mut caller : wasmtime:: Caller < ' _ , WasmInstanceData > ,
577+ gas_used : u32 |
578+ -> anyhow:: Result < ( ) > {
582579 // Gas metering has a relevant execution cost cost, being called tens of thousands
583580 // of times per handler, but it's not worth having a stopwatch section here because
584581 // the cost of measuring would be greater than the cost of `consume_host_fn`. Last
585582 // time this was benchmarked it took < 100ns to run.
586- if let Err ( e) = gas. consume_host_fn_with_metrics ( gas_used. saturating_into ( ) , "gas" )
583+ if let Err ( e) = caller
584+ . data ( )
585+ . gas
586+ . consume_host_fn_with_metrics ( gas_used. saturating_into ( ) , "gas" )
587587 {
588- deterministic_host_trap . store ( true , Ordering :: SeqCst ) ;
588+ caller . data_mut ( ) . deterministic_host_trap = true ;
589589 return Err ( e. into ( ) ) ;
590590 }
591591
592592 Ok ( ( ) )
593- } ) ? ;
594- }
593+ } ,
594+ ) ? ;
595595
596596 let instance = linker
597597 . instantiate_async ( store. as_context_mut ( ) , & valid_module. module )
0 commit comments