Skip to content

Commit 243ce31

Browse files
committed
inline metering with injected gas function
1 parent 0638224 commit 243ce31

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

wasm-utils/cli/gas/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ fn main() {
1313
return;
1414
}
1515

16+
/*
1617
let memory_page_cost = 256 * 1024; // 256k gas for 1 page (64k) of memory
17-
18-
// let config = pwasm_utils::rules::Set::default()
19-
// .with_forbidden_floats() // Reject floating point opreations.
20-
// .with_grow_cost(memory_page_cost);
18+
let config = pwasm_utils::rules::Set::default()
19+
.with_forbidden_floats() // Reject floating point opreations.
20+
.with_grow_cost(memory_page_cost);
21+
*/
2122

2223
let config = pwasm_utils::rules::Set::default()
2324
.with_forbidden_floats();

wasm-utils/src/gas.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,50 @@ impl Counter {
136136
}
137137
}
138138

139+
fn inject_inline_gas(module: elements::Module) -> elements::Module {
140+
use parity_wasm::elements::Instruction::*;
141+
142+
static DEFAULT_START_GAS: i32 = 2000000000; // 4 billion is too big for signed integer
143+
144+
let global_gas_index = module.globals_space() as u32;
145+
println!("total globals before injecting gas global: {:?}", global_gas_index);
146+
147+
let b = builder::from_module(module);
148+
149+
let mut b2 = b.global().mutable()
150+
.value_type().i32().init_expr(elements::Instruction::I32Const(DEFAULT_START_GAS))
151+
.build()
152+
.export()
153+
.field("gas_global")
154+
.internal().global(global_gas_index)
155+
.build();
156+
157+
b2.push_function(
158+
builder::function()
159+
.signature().param().i32().build()
160+
.body()
161+
.with_instructions(elements::Instructions::new(vec![
162+
GetGlobal(global_gas_index),
163+
GetLocal(0),
164+
I32Sub,
165+
TeeLocal(0), // overwrite local 0 is a workaround to keep wasm2wat generate names working (dont know how to declare local with builder)
166+
I32Const(0 as i32),
167+
I32LtS,
168+
If(elements::BlockType::NoResult),
169+
Unreachable,
170+
End,
171+
GetLocal(0),
172+
SetGlobal(global_gas_index),
173+
End,
174+
]))
175+
.build()
176+
.build()
177+
);
178+
179+
b2.build()
180+
181+
}
182+
139183
fn inject_grow_counter(instructions: &mut elements::Instructions, grow_counter_func: u32) -> usize {
140184
use parity_wasm::elements::Instruction::*;
141185
let mut counter = 0;
@@ -312,8 +356,12 @@ pub fn inject_counter(
312356
pub fn inject_gas_counter(module: elements::Module, rules: &rules::Set)
313357
-> Result<elements::Module, elements::Module>
314358
{
359+
let mbuilder = builder::from_module(module);
360+
let mut module = mbuilder.build();
361+
362+
/*
363+
// we are doing inline gas metering, so disable the external metering
315364
// Injecting gas counting external
316-
let mut mbuilder = builder::from_module(module);
317365
let import_sig = mbuilder.push_signature(
318366
builder::signature()
319367
.param().i32()
@@ -335,7 +383,16 @@ pub fn inject_gas_counter(module: elements::Module, rules: &rules::Set)
335383
// (substract all imports that are NOT functions)
336384
337385
let gas_func = module.import_count(elements::ImportCountType::Function) as u32 - 1;
338-
let total_func = module.functions_space() as u32;
386+
*/
387+
388+
389+
// for inline gas function
390+
let gas_func = module.functions_space() as u32;
391+
392+
// need to inject inline gas function after the metering statements,
393+
// or the gas function itself with be metered and recursively call itself
394+
395+
let total_func = gas_func + 1;
339396
let mut need_grow_counter = false;
340397
let mut error = false;
341398

@@ -378,6 +435,9 @@ pub fn inject_gas_counter(module: elements::Module, rules: &rules::Set)
378435

379436
if error { return Err(module); }
380437

438+
// metering calls have been injected, now inject inline gas func
439+
module = inject_inline_gas(module);
440+
381441
if need_grow_counter { Ok(add_grow_counter(module, rules, gas_func)) } else { Ok(module) }
382442
}
383443

0 commit comments

Comments
 (0)