mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-06-10 09:01:07 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 10fd3529f2 | |||
| 32ae9f8478 | |||
| 8bfdb41d01 | |||
| 659d3bf12c | |||
| 5b2f75a066 | |||
| 25ff883bbd |
+2
-5
@@ -22,9 +22,7 @@ codegen-units = 1
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parity-wasm = { version = "0.45", default-features = false }
|
parity-wasm = { version = "0.45", default-features = false }
|
||||||
log = { version = "0.4.8", default-features = false, optional = true }
|
log = "0.4"
|
||||||
test-log = { version = "0.2", optional = true }
|
|
||||||
env_logger = { version = "0.9", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
binaryen = "0.12"
|
binaryen = "0.12"
|
||||||
@@ -32,11 +30,10 @@ criterion = "0.3"
|
|||||||
diff = "0.1"
|
diff = "0.1"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
wat = "1"
|
wat = "1"
|
||||||
wasmparser = "0.87"
|
wasmparser = "0.88"
|
||||||
wasmprinter = "0.2"
|
wasmprinter = "0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = ["parity-wasm/std"]
|
std = ["parity-wasm/std"]
|
||||||
sign_ext = ["parity-wasm/sign_ext"]
|
sign_ext = ["parity-wasm/sign_ext"]
|
||||||
trace-log = ["dep:log", "dep:test-log", "dep:env_logger"]
|
|
||||||
+3
-3
@@ -1,6 +1,8 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
mod export_globals;
|
mod export_globals;
|
||||||
pub mod gas_metering;
|
pub mod gas_metering;
|
||||||
@@ -8,6 +10,4 @@ mod stack_limiter;
|
|||||||
|
|
||||||
pub use export_globals::export_mutable_globals;
|
pub use export_globals::export_mutable_globals;
|
||||||
pub use parity_wasm;
|
pub use parity_wasm;
|
||||||
pub use stack_limiter::{
|
pub use stack_limiter::{compute_stack_cost, inject as inject_stack_limiter};
|
||||||
compute_stack_cost, compute_stack_height_weight, inject as inject_stack_limiter,
|
|
||||||
};
|
|
||||||
|
|||||||
+400
-443
File diff suppressed because it is too large
Load Diff
+10
-36
@@ -6,6 +6,7 @@ use parity_wasm::{
|
|||||||
builder,
|
builder,
|
||||||
elements::{self, Instruction, Instructions, Type},
|
elements::{self, Instruction, Instructions, Type},
|
||||||
};
|
};
|
||||||
|
pub use max_height::StackHeightStats;
|
||||||
|
|
||||||
/// Macro to generate preamble and postamble.
|
/// Macro to generate preamble and postamble.
|
||||||
macro_rules! instrument_call {
|
macro_rules! instrument_call {
|
||||||
@@ -40,7 +41,7 @@ mod thunk;
|
|||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
stack_height_global_idx: u32,
|
stack_height_global_idx: u32,
|
||||||
func_stack_costs: Vec<u32>,
|
func_stack_costs: Vec<StackHeightStats>,
|
||||||
stack_limit: u32,
|
stack_limit: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,11 @@ impl Context {
|
|||||||
|
|
||||||
/// Returns `stack_cost` for `func_idx`.
|
/// Returns `stack_cost` for `func_idx`.
|
||||||
fn stack_cost(&self, func_idx: u32) -> Option<u32> {
|
fn stack_cost(&self, func_idx: u32) -> Option<u32> {
|
||||||
self.func_stack_costs.get(func_idx as usize).cloned()
|
if let Some(stats) = self.func_stack_costs.get(func_idx as usize) {
|
||||||
|
Some(stats.total_cost)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns stack limit specified by the rules.
|
/// Returns stack limit specified by the rules.
|
||||||
@@ -154,7 +159,7 @@ fn generate_stack_height_global(module: &mut elements::Module) -> u32 {
|
|||||||
/// Calculate stack costs for all functions.
|
/// Calculate stack costs for all functions.
|
||||||
///
|
///
|
||||||
/// Returns a vector with a stack cost for each function, including imports.
|
/// Returns a vector with a stack cost for each function, including imports.
|
||||||
pub fn compute_stack_costs(module: &elements::Module) -> Result<Vec<u32>, &'static str> {
|
fn compute_stack_costs(module: &elements::Module) -> Result<Vec<StackHeightStats>, &'static str> {
|
||||||
let func_imports = module.import_count(elements::ImportCountType::Function);
|
let func_imports = module.import_count(elements::ImportCountType::Function);
|
||||||
|
|
||||||
// TODO: optimize!
|
// TODO: optimize!
|
||||||
@@ -162,7 +167,7 @@ pub fn compute_stack_costs(module: &elements::Module) -> Result<Vec<u32>, &'stat
|
|||||||
.map(|func_idx| {
|
.map(|func_idx| {
|
||||||
if func_idx < func_imports {
|
if func_idx < func_imports {
|
||||||
// We can't calculate stack_cost of the import functions.
|
// We can't calculate stack_cost of the import functions.
|
||||||
Ok(0)
|
Ok(Default::default())
|
||||||
} else {
|
} else {
|
||||||
compute_stack_cost(func_idx as u32, module)
|
compute_stack_cost(func_idx as u32, module)
|
||||||
}
|
}
|
||||||
@@ -173,7 +178,7 @@ pub fn compute_stack_costs(module: &elements::Module) -> Result<Vec<u32>, &'stat
|
|||||||
/// Stack cost of the given *defined* function is the sum of it's locals count (that is,
|
/// Stack cost of the given *defined* function is the sum of it's locals count (that is,
|
||||||
/// number of arguments plus number of local variables) and the maximal stack
|
/// number of arguments plus number of local variables) and the maximal stack
|
||||||
/// height.
|
/// height.
|
||||||
pub fn compute_stack_cost(func_idx: u32, module: &elements::Module) -> Result<u32, &'static str> {
|
pub fn compute_stack_cost(func_idx: u32, module: &elements::Module) -> Result<StackHeightStats, &'static str> {
|
||||||
// To calculate the cost of a function we need to convert index from
|
// To calculate the cost of a function we need to convert index from
|
||||||
// function index space to defined function spaces.
|
// function index space to defined function spaces.
|
||||||
let func_imports = module.import_count(elements::ImportCountType::Function) as u32;
|
let func_imports = module.import_count(elements::ImportCountType::Function) as u32;
|
||||||
@@ -181,37 +186,6 @@ pub fn compute_stack_cost(func_idx: u32, module: &elements::Module) -> Result<u3
|
|||||||
.checked_sub(func_imports)
|
.checked_sub(func_imports)
|
||||||
.ok_or("This should be a index of a defined function")?;
|
.ok_or("This should be a index of a defined function")?;
|
||||||
|
|
||||||
let code_section =
|
|
||||||
module.code_section().ok_or("Due to validation code section should exists")?;
|
|
||||||
let body = &code_section
|
|
||||||
.bodies()
|
|
||||||
.get(defined_func_idx as usize)
|
|
||||||
.ok_or("Function body is out of bounds")?;
|
|
||||||
|
|
||||||
let mut locals_count: u32 = 0;
|
|
||||||
for local_group in body.locals() {
|
|
||||||
locals_count =
|
|
||||||
locals_count.checked_add(local_group.count()).ok_or("Overflow in local count")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (max_stack_height, _max_stack_weight) = max_height::compute(defined_func_idx, module)?;
|
|
||||||
|
|
||||||
locals_count
|
|
||||||
.checked_add(max_stack_height)
|
|
||||||
.ok_or("Overflow in adding locals_count and max_stack_height")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stack height is the measurement maximum wasm stack height reached during function execution.
|
|
||||||
/// Stack weight is weighted value which approximates a real stack size on x64 architecture.
|
|
||||||
pub fn compute_stack_height_weight(
|
|
||||||
func_idx: u32,
|
|
||||||
module: &elements::Module,
|
|
||||||
) -> Result<(u32, u32), &'static str> {
|
|
||||||
let func_imports = module.import_count(elements::ImportCountType::Function) as u32;
|
|
||||||
let defined_func_idx = func_idx
|
|
||||||
.checked_sub(func_imports)
|
|
||||||
.ok_or("This should be a index of a defined function")?;
|
|
||||||
|
|
||||||
max_height::compute(defined_func_idx, module)
|
max_height::compute(defined_func_idx, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user