fn injections(
    code: &[Instruction],
    instruction_cost_table: &InstructionCostTable,
) -> Vec<InjectionPoint> {
    let mut res = Vec::new();
    let mut stack = Vec::new();
    use Instruction::*;
    // The function itself is a re-entrant code block.
    let mut curr = InjectionPoint::new_static_cost(0, Scope::ReentrantBlockStart);
    for (position, i) in code.iter().enumerate() {
        curr.cost_detail
            .increment_cost(instruction_cost_table.cost(i));
        match i {
            // Start of a re-entrant code block.
            Loop(_) => {
                stack.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::ReentrantBlockStart);
            }
            // Start of a non re-entrant code block.
            If(_) | Block(_) => {
                stack.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::NonReentrantBlockStart);
            }
            // End of a code block but still more code left.
            Else | Br(_) | BrIf(_) | BrTable(_) => {
                res.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::BlockEnd);
            }
            // `End` signals the end of a code block. If there's nothing more on the stack, we've
            // gone through all the code.
            End => {
                res.push(curr);
                curr = match stack.pop() {
                    Some(val) => val,
                    None => break,
                };
            }
            // Bulk memory instructions require injected metering __before__ the instruction
            // executes so that size arguments can be read from the stack at runtime.
            Bulk(BulkInstruction::MemoryFill)
            | Bulk(BulkInstruction::MemoryCopy)
            | Bulk(BulkInstruction::MemoryInit(_))
            | Bulk(BulkInstruction::TableCopy)
            | Bulk(BulkInstruction::TableInit(_)) => {
                res.push(InjectionPoint::new_dynamic_cost(position));
            }
            // Nothing special to be done for other instructions.
            _ => (),
        }
    }
    res.sort_by_key(|k| k.position);
    res
}
// This function scans through the Wasm code and creates an injection point
// at the beginning of every basic block (straight-line sequence of instructions
// with no branches) and before each bulk memory instruction. An injection point
// contains a "hint" about the context of every basic block, specifically if
// it's re-entrant or not.
This function scans through the Wasm code and creates an injection point
at the beginning of every basic block (straight-line sequence of instructions
with no branches) and before each bulk memory instruction. An injection point
contains a "hint" about the context of every basic block, specifically if
it's re-entrant or not.
This function scans through the Wasm code and creates an injection point at the beginning of every basic block ( straight - line sequence of instructions with no branches ) and before each bulk memory instruction . An injection point contains a " hint " about the context of every basic block specifically if it ' s re - entrant or not .
fn injections(
    code: &[Instruction],
    instruction_cost_table: &InstructionCostTable,
) -> Vec<InjectionPoint> {
    let mut res = Vec::new();
    let mut stack = Vec::new();
    use Instruction::*;
    // The function itself is a re-entrant code block.
    let mut curr = InjectionPoint::new_static_cost(0, Scope::ReentrantBlockStart);
    for (position, i) in code.iter().enumerate() {
        curr.cost_detail
            .increment_cost(instruction_cost_table.cost(i));
        match i {
            // Start of a re-entrant code block.
            Loop(_) => {
                stack.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::ReentrantBlockStart);
            }
            // Start of a non re-entrant code block.
            If(_) | Block(_) => {
                stack.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::NonReentrantBlockStart);
            }
            // End of a code block but still more code left.
            Else | Br(_) | BrIf(_) | BrTable(_) => {
                res.push(curr);
                curr = InjectionPoint::new_static_cost(position + 1, Scope::BlockEnd);
            }
            // `End` signals the end of a code block. If there's nothing more on the stack, we've
            // gone through all the code.
            End => {
                res.push(curr);
                curr = match stack.pop() {
                    Some(val) => val,
                    None => break,
                };
            }
            // Bulk memory instructions require injected metering __before__ the instruction
            // executes so that size arguments can be read from the stack at runtime.
            Bulk(BulkInstruction::MemoryFill)
            | Bulk(BulkInstruction::MemoryCopy)
            | Bulk(BulkInstruction::MemoryInit(_))
            | Bulk(BulkInstruction::TableCopy)
            | Bulk(BulkInstruction::TableInit(_)) => {
                res.push(InjectionPoint::new_dynamic_cost(position));
            }
            // Nothing special to be done for other instructions.
            _ => (),
        }
    }
    res.sort_by_key(|k| k.position);
    res
}
fn injections ( code : & [ Instruction ] , instruction_cost_table : & InstructionCostTable , ) -> Vec < InjectionPoint > { let mut res = Vec :: new ( ) ; let mut stack = Vec :: new ( ) ; use Instruction :: * ; // The function itself is a re-entrant code block. let mut curr = InjectionPoint :: new_static_cost ( 0 , Scope :: ReentrantBlockStart ) ; for ( position , i ) in code . iter ( ) . enumerate ( ) { curr . cost_detail . increment_cost ( instruction_cost_table . cost ( i ) ) ; match i { // Start of a re-entrant code block. Loop ( _ ) => { stack . push ( curr ) ; curr = InjectionPoint :: new_static_cost ( position + 1 , Scope :: ReentrantBlockStart ) ; } // Start of a non re-entrant code block. If ( _ ) | Block ( _ ) => { stack . push ( curr ) ; curr = InjectionPoint :: new_static_cost ( position + 1 , Scope :: NonReentrantBlockStart ) ; } // End of a code block but still more code left. Else | Br ( _ ) | BrIf ( _ ) | BrTable ( _ ) => { res . push ( curr ) ; curr = InjectionPoint :: new_static_cost ( position + 1 , Scope :: BlockEnd ) ; } // `End` signals the end of a code block. If there's nothing more on the stack, we've // gone through all the code. End => { res . push ( curr ) ; curr = match stack . pop ( ) { Some ( val ) => val , None => break , } ; } // Bulk memory instructions require injected metering __before__ the instruction // executes so that size arguments can be read from the stack at runtime. Bulk ( BulkInstruction :: MemoryFill ) | Bulk ( BulkInstruction :: MemoryCopy ) | Bulk ( BulkInstruction :: MemoryInit ( _ ) ) | Bulk ( BulkInstruction :: TableCopy ) | Bulk ( BulkInstruction :: TableInit ( _ ) ) => { res . push ( InjectionPoint :: new_dynamic_cost ( position ) ) ; } // Nothing special to be done for other instructions. _ => ( ) , } } res . sort_by_key ( | k | k . position ) ; res }
This function scans through the Wasm code and creates an injection point
at the beginning of every basic block (straight-line sequence of instructions
with no branches) and before each bulk memory instruction.
This function scans through the Wasm code and creates an injection point at the beginning of every basic block ( straight - line sequence of instructions with no branches ) and before each bulk memory instruction .
code
&[Instruction]
instruction_cost_table
&InstructionCostTable
code
&[Instruction]
instruction_cost_table
&InstructionCostTable