// This function iterates over the injection points, and inserts three different
// pieces of Wasm code:
// - we insert a simple instructions counter decrementation in a beginning of
//   every non-reentrant block
// - we insert a counter decrementation and an overflow check at the beginning
//   of every reentrant block (a loop or a function call).
// - we insert a function call before each dynamic cost instruction which
//   performs an overflow check and then decrements the counter by the value at
//   the top of the stack.
This function iterates over the injection points, and inserts three different
pieces of Wasm code:
we insert a simple instructions counter decrementation in a beginning of
every non-reentrant block
we insert a counter decrementation and an overflow check at the beginning
of every reentrant block (a loop or a function call).
we insert a function call before each dynamic cost instruction which
performs an overflow check and then decrements the counter by the value at
the top of the stack.
This function iterates over the injection points and inserts three different pieces of Wasm code : we insert a simple instructions counter decrementation in a beginning of every non - reentrant block we insert a counter decrementation and an overflow check at the beginning of every reentrant block ( a loop or a function call ) . we insert a function call before each dynamic cost instruction which performs an overflow check and then decrements the counter by the value at the top of the stack .
fn inject_metering(
    code: &mut Instructions,
    instruction_cost_table: &InstructionCostTable,
    export_data_module: &ExportModuleData,
) {
    let points = injections(code.elements(), instruction_cost_table);
    let points = points.iter().filter(|point| match point.cost_detail {
        InjectionPointCostDetail::StaticCost {
            scope: Scope::ReentrantBlockStart,
            cost: _,
        } => true,
        InjectionPointCostDetail::StaticCost { scope: _, cost } => cost > 0,
        InjectionPointCostDetail::DynamicCost => true,
    });
    let orig_elems = code.elements();
    let mut elems: Vec<Instruction> = Vec::new();
    let mut last_injection_position = 0;
    for point in points {
        elems.extend_from_slice(&orig_elems[last_injection_position..point.position]);
        match point.cost_detail {
            InjectionPointCostDetail::StaticCost { scope, cost } => {
                elems.extend_from_slice(&[
                    Instruction::GetGlobal(export_data_module.instructions_counter_ix),
                    Instruction::I64Const(cost as i64),
                    Instruction::I64Sub,
                    Instruction::SetGlobal(export_data_module.instructions_counter_ix),
                ]);
                if scope == Scope::ReentrantBlockStart {
                    elems.extend_from_slice(&[
                        Instruction::GetGlobal(export_data_module.instructions_counter_ix),
                        Instruction::I64Const(0),
                        Instruction::I64LtS,
                        Instruction::If(BlockType::NoResult),
                        Instruction::Call(export_data_module.out_of_instructions_fn),
                        Instruction::End,
                    ]);
                }
            }
            InjectionPointCostDetail::DynamicCost => {
                elems.extend_from_slice(&[Instruction::Call(
                    export_data_module.decr_instruction_counter_fn,
                )]);
            }
        }
        last_injection_position = point.position;
    }
    elems.extend_from_slice(&orig_elems[last_injection_position..]);
    *code.elements_mut() = elems;
}
fn inject_metering ( code : & mut Instructions , instruction_cost_table : & InstructionCostTable , export_data_module : & ExportModuleData , ) { let points = injections ( code . elements ( ) , instruction_cost_table ) ; let points = points . iter ( ) . filter ( | point | match point . cost_detail { InjectionPointCostDetail :: StaticCost { scope : Scope :: ReentrantBlockStart , cost : _ , } => true , InjectionPointCostDetail :: StaticCost { scope : _ , cost } => cost > 0 , InjectionPointCostDetail :: DynamicCost => true , } ) ; let orig_elems = code . elements ( ) ; let mut elems : Vec < Instruction > = Vec :: new ( ) ; let mut last_injection_position = 0 ; for point in points { elems . extend_from_slice ( & orig_elems [ last_injection_position .. point . position ] ) ; match point . cost_detail { InjectionPointCostDetail :: StaticCost { scope , cost } => { elems . extend_from_slice ( & [ Instruction :: GetGlobal ( export_data_module . instructions_counter_ix ) , Instruction :: I64Const ( cost as i64 ) , Instruction :: I64Sub , Instruction :: SetGlobal ( export_data_module . instructions_counter_ix ) , ] ) ; if scope == Scope :: ReentrantBlockStart { elems . extend_from_slice ( & [ Instruction :: GetGlobal ( export_data_module . instructions_counter_ix ) , Instruction :: I64Const ( 0 ) , Instruction :: I64LtS , Instruction :: If ( BlockType :: NoResult ) , Instruction :: Call ( export_data_module . out_of_instructions_fn ) , Instruction :: End , ] ) ; } } InjectionPointCostDetail :: DynamicCost => { elems . extend_from_slice ( & [ Instruction :: Call ( export_data_module . decr_instruction_counter_fn , ) ] ) ; } } last_injection_position = point . position ; } elems . extend_from_slice ( & orig_elems [ last_injection_position .. ] ) ; * code . elements_mut ( ) = elems ; }
This function iterates over the injection points, and inserts three different
pieces of Wasm code:
 we insert a simple instructions counter decrementation in a beginning of
every non-reentrant block
 we insert a counter decrementation and an overflow check at the beginning
of every reentrant block (a loop or a function call).
This function iterates over the injection points and inserts three different pieces of Wasm code : we insert a simple instructions counter decrementation in a beginning of every non - reentrant block we insert a counter decrementation and an overflow check at the beginning of every reentrant block ( a loop or a function call ) .
code
&mut Instructions
instruction_cost_table
&InstructionCostTable
export_data_module
&ExportModuleData