fn export_xform(cx: &mut Context, export: Export, instrs: &mut Vec<InstructionData>) {
    let mut to_delete = Vec::new();
    let mut iter = instrs.iter().enumerate();
    let mut args = Vec::new();

    // Mutate instructions leading up to the `CallExport` instruction. We
    // maintain a stack of indicators whether the element at that stack slot is
    // unknown (`None`) or whether it's an owned/borrowed anyref
    // (`Some(owned)`).
    //
    // Note that we're going to delete the `I32FromAnyref*` instructions, so we
    // also maintain indices of the instructions to delete.
    while let Some((i, instr)) = iter.next() {
        match instr.instr {
            Instruction::CallExport(_) | Instruction::CallTableElement(_) => break,
            Instruction::I32FromAnyrefOwned => {
                args.pop();
                args.push(Some(true));
                to_delete.push(i);
            }
            Instruction::I32FromAnyrefBorrow => {
                args.pop();
                args.push(Some(false));
                to_delete.push(i);
            }
            _ => match instr.stack_change {
                StackChange::Modified { pushed, popped } => {
                    for _ in 0..popped {
                        args.pop();
                    }
                    for _ in 0..pushed {
                        args.push(None);
                    }
                }
                StackChange::Unknown => {
                    panic!("must have stack change data");
                }
            },
        }
    }

    // If one of the instructions after the call is an `AnyrefLoadOwned` then we
    // know that the function returned an anyref. Currently `&'static Anyref`
    // can't be done as a return value, so this is the only case we handle here.
    let mut ret_anyref = false;
    while let Some((i, instr)) = iter.next() {
        match instr.instr {
            Instruction::AnyrefLoadOwned => {
                ret_anyref = true;
                to_delete.push(i);
            }
            _ => {}
        }
    }

    // Filter down our list of arguments to just the ones that are anyref
    // values.
    let args = args
        .iter()
        .enumerate()
        .filter_map(|(i, owned)| owned.map(|owned| (i, owned)))
        .collect::<Vec<_>>();

    // ... and register this entire transformation with the anyref
    // transformation pass.
    match export {
        Export::Export(id) => {
            cx.export_xform(id, &args, ret_anyref);
        }
        Export::TableElement { idx, call_idx } => {
            if let Some(new_idx) = cx.table_element_xform(idx, &args, ret_anyref) {
                instrs[call_idx].instr = Instruction::CallTableElement(new_idx);
            }
        }
    }

    // Delete all unnecessary anyref management instructions. We're going to
    // sink these instructions into the wasm module itself.
    for idx in to_delete.into_iter().rev() {
        instrs.remove(idx);
    }
}
/// Adapts the `instrs` of an adapter function that calls an export.
///
/// The `instrs` must be generated by wasm-bindgen itself and follow the
/// pattern matched below to pass off to the anyref transformation pass. The
/// signature of the adapter doesn't change (it remains as anyref-aware) but the
/// signature of the export we're calling will change during the transformation.
Adapts the `instrs` of an adapter function that calls an export.
The `instrs` must be generated by wasm-bindgen itself and follow the
pattern matched below to pass off to the anyref transformation pass. The
signature of the adapter doesn't change (it remains as anyref-aware) but the
signature of the export we're calling will change during the transformation.
Adapts the ` instrs ` of an adapter function that calls an export . The ` instrs ` must be generated by wasm - bindgen itself and follow the pattern matched below to pass off to the anyref transformation pass . The signature of the adapter doesn ' t change ( it remains as anyref - aware ) but the signature of the export we ' re calling will change during the transformation .
fn export_xform(cx: &mut Context, export: Export, instrs: &mut Vec<InstructionData>) {
    let mut to_delete = Vec::new();
    let mut iter = instrs.iter().enumerate();
    let mut args = Vec::new();
    // Mutate instructions leading up to the `CallExport` instruction. We
    // maintain a stack of indicators whether the element at that stack slot is
    // unknown (`None`) or whether it's an owned/borrowed anyref
    // (`Some(owned)`).
    //
    // Note that we're going to delete the `I32FromAnyref*` instructions, so we
    // also maintain indices of the instructions to delete.
    while let Some((i, instr)) = iter.next() {
        match instr.instr {
            Instruction::CallExport(_) | Instruction::CallTableElement(_) => break,
            Instruction::I32FromAnyrefOwned => {
                args.pop();
                args.push(Some(true));
                to_delete.push(i);
            }
            Instruction::I32FromAnyrefBorrow => {
                args.pop();
                args.push(Some(false));
                to_delete.push(i);
            }
            _ => match instr.stack_change {
                StackChange::Modified { pushed, popped } => {
                    for _ in 0..popped {
                        args.pop();
                    }
                    for _ in 0..pushed {
                        args.push(None);
                    }
                }
                StackChange::Unknown => {
                    panic!("must have stack change data");
                }
            },
        }
    }
    // If one of the instructions after the call is an `AnyrefLoadOwned` then we
    // know that the function returned an anyref. Currently `&'static Anyref`
    // can't be done as a return value, so this is the only case we handle here.
    let mut ret_anyref = false;
    while let Some((i, instr)) = iter.next() {
        match instr.instr {
            Instruction::AnyrefLoadOwned => {
                ret_anyref = true;
                to_delete.push(i);
            }
            _ => {}
        }
    }
    // Filter down our list of arguments to just the ones that are anyref
    // values.
    let args = args
        .iter()
        .enumerate()
        .filter_map(|(i, owned)| owned.map(|owned| (i, owned)))
        .collect::<Vec<_>>();
    // ... and register this entire transformation with the anyref
    // transformation pass.
    match export {
        Export::Export(id) => {
            cx.export_xform(id, &args, ret_anyref);
        }
        Export::TableElement { idx, call_idx } => {
            if let Some(new_idx) = cx.table_element_xform(idx, &args, ret_anyref) {
                instrs[call_idx].instr = Instruction::CallTableElement(new_idx);
            }
        }
    }
    // Delete all unnecessary anyref management instructions. We're going to
    // sink these instructions into the wasm module itself.
    for idx in to_delete.into_iter().rev() {
        instrs.remove(idx);
    }
}
fn export_xform ( cx : & mut Context , export : Export , instrs : & mut Vec < InstructionData > ) { let mut to_delete = Vec :: new ( ) ; let mut iter = instrs . iter ( ) . enumerate ( ) ; let mut args = Vec :: new ( ) ; // Mutate instructions leading up to the `CallExport` instruction. We // maintain a stack of indicators whether the element at that stack slot is // unknown (`None`) or whether it's an owned/borrowed anyref // (`Some(owned)`). // // Note that we're going to delete the `I32FromAnyref*` instructions, so we // also maintain indices of the instructions to delete. while let Some ( ( i , instr ) ) = iter . next ( ) { match instr . instr { Instruction :: CallExport ( _ ) | Instruction :: CallTableElement ( _ ) => break , Instruction :: I32FromAnyrefOwned => { args . pop ( ) ; args . push ( Some ( true ) ) ; to_delete . push ( i ) ; } Instruction :: I32FromAnyrefBorrow => { args . pop ( ) ; args . push ( Some ( false ) ) ; to_delete . push ( i ) ; } _ => match instr . stack_change { StackChange :: Modified { pushed , popped } => { for _ in 0 .. popped { args . pop ( ) ; } for _ in 0 .. pushed { args . push ( None ) ; } } StackChange :: Unknown => { panic ! ( " " ) ; } } , } } // If one of the instructions after the call is an `AnyrefLoadOwned` then we // know that the function returned an anyref. Currently `&'static Anyref` // can't be done as a return value, so this is the only case we handle here. let mut ret_anyref = false ; while let Some ( ( i , instr ) ) = iter . next ( ) { match instr . instr { Instruction :: AnyrefLoadOwned => { ret_anyref = true ; to_delete . push ( i ) ; } _ => { } } } // Filter down our list of arguments to just the ones that are anyref // values. let args = args . iter ( ) . enumerate ( ) . filter_map ( | ( i , owned ) | owned . map ( | owned | ( i , owned ) ) ) . collect :: < Vec < _ > > ( ) ; // ... and register this entire transformation with the anyref // transformation pass. match export { Export :: Export ( id ) => { cx . export_xform ( id , & args , ret_anyref ) ; } Export :: TableElement { idx , call_idx } => { if let Some ( new_idx ) = cx . table_element_xform ( idx , & args , ret_anyref ) { instrs [ call_idx ] . instr = Instruction :: CallTableElement ( new_idx ) ; } } } // Delete all unnecessary anyref management instructions. We're going to // sink these instructions into the wasm module itself. for idx in to_delete . into_iter ( ) . rev ( ) { instrs . remove ( idx ) ; } }
Adapts the `instrs` of an adapter function that calls an export.
Adapts the ` instrs ` of an adapter function that calls an export .
cx
&mut Context
export
Export
instrs
&mut Vec<InstructionData>
cx
&mut Context
export
Export
instrs
&mut Vec<InstructionData>