fn generate_inline_function_body(&self, func_target: &FunctionTarget<'_>) {
        let code = func_target.get_bytecode();

        // Construct context for bytecode translation.
        let mut context = BytecodeContext::default();

        // Walk over the bytecode and collect various context information.
        for bytecode in code {
            match bytecode {
                Call(_, dsts, oper, _) => {
                    use Operation::*;
                    match oper {
                        BorrowLoc | BorrowGlobal(..) | BorrowField(..) => {
                            let dst = dsts[0];
                            let ty = func_target.get_local_type(dst);
                            if ty.is_mutable_reference() {
                                // Track that we create a mutable reference here.
                                context.mutable_refs.insert(dst);
                            }
                        }
                        _ => {}
                    }
                }
                Assign(_, dst, src, AssignKind::Move) | Assign(_, dst, src, AssignKind::Store) => {
                    // Propagate information from src to dst.
                    if context.mutable_refs.contains(src) {
                        context.mutable_refs.insert(*dst);
                    }
                }
                _ => {}
            }
        }

        // Be sure to set back location to the whole function definition as a default, otherwise
        // we may get unassigned code locations associated with condition locations.
        self.writer.set_location(&func_target.get_loc());

        emitln!(self.writer, "{");
        self.writer.indent();

        // Generate local variable declarations. They need to appear first in boogie.
        emitln!(self.writer, "// declare local variables");
        let num_args = func_target.get_parameter_count();
        for i in num_args..func_target.get_local_count() {
            let local_name = func_target.get_local_name(i);
            let local_type = func_target.get_local_type(i);
            emitln!(
                self.writer,
                "var {}: {}; // {}",
                local_name.display(func_target.symbol_pool()),
                boogie_local_type(local_type),
                boogie_type_value(self.module_env.env, local_type)
            );
        }
        emitln!(self.writer, "var $tmp: $Value;");
        emitln!(self.writer, "var $saved_m: $Memory;");

        emitln!(self.writer, "\n// initialize function execution");
        emitln!(self.writer, "assert !$abort_flag;");
        emitln!(self.writer, "$saved_m := $m;");

        emitln!(self.writer, "\n// bytecode translation starts here");

        // Generate bytecode
        for (offset, bytecode) in code.iter().enumerate() {
            self.translate_bytecode(func_target, &context, offset as CodeOffset, bytecode);
        }

        // Generate abort exit.
        let end_loc = func_target.get_loc().at_end();
        self.writer.set_location(&end_loc);
        self.writer.unindent();
        emitln!(self.writer, "Abort:");
        self.writer.indent();
        emitln!(self.writer, "$abort_flag := true;");
        emitln!(self.writer, "$m := $saved_m;");
        for (i, ty) in func_target.get_return_types().iter().enumerate() {
            let ret_str = format!("$ret{}", i);
            if ty.is_reference() {
                emitln!(self.writer, "{} := $DefaultReference;", &ret_str);
            } else {
                emitln!(self.writer, "{} := $DefaultValue();", &ret_str);
            }
        }
        self.writer.unindent();
        emitln!(self.writer, "}");
    }
/// This generates boogie code for everything after the function signature
/// The function body is only generated for the "inline" version of the function.
This generates boogie code for everything after the function signature
The function body is only generated for the "inline" version of the function.
This generates boogie code for everything after the function signature The function body is only generated for the " inline " version of the function .
fn generate_inline_function_body(&self, func_target: &FunctionTarget<'_>) {
        let code = func_target.get_bytecode();
        // Construct context for bytecode translation.
        let mut context = BytecodeContext::default();
        // Walk over the bytecode and collect various context information.
        for bytecode in code {
            match bytecode {
                Call(_, dsts, oper, _) => {
                    use Operation::*;
                    match oper {
                        BorrowLoc | BorrowGlobal(..) | BorrowField(..) => {
                            let dst = dsts[0];
                            let ty = func_target.get_local_type(dst);
                            if ty.is_mutable_reference() {
                                // Track that we create a mutable reference here.
                                context.mutable_refs.insert(dst);
                            }
                        }
                        _ => {}
                    }
                }
                Assign(_, dst, src, AssignKind::Move) | Assign(_, dst, src, AssignKind::Store) => {
                    // Propagate information from src to dst.
                    if context.mutable_refs.contains(src) {
                        context.mutable_refs.insert(*dst);
                    }
                }
                _ => {}
            }
        }
        // Be sure to set back location to the whole function definition as a default, otherwise
        // we may get unassigned code locations associated with condition locations.
        self.writer.set_location(&func_target.get_loc());
        emitln!(self.writer, "{");
        self.writer.indent();
        // Generate local variable declarations. They need to appear first in boogie.
        emitln!(self.writer, "// declare local variables");
        let num_args = func_target.get_parameter_count();
        for i in num_args..func_target.get_local_count() {
            let local_name = func_target.get_local_name(i);
            let local_type = func_target.get_local_type(i);
            emitln!(
                self.writer,
                "var {}: {}; // {}",
                local_name.display(func_target.symbol_pool()),
                boogie_local_type(local_type),
                boogie_type_value(self.module_env.env, local_type)
            );
        }
        emitln!(self.writer, "var $tmp: $Value;");
        emitln!(self.writer, "var $saved_m: $Memory;");
        emitln!(self.writer, "\n// initialize function execution");
        emitln!(self.writer, "assert !$abort_flag;");
        emitln!(self.writer, "$saved_m := $m;");
        emitln!(self.writer, "\n// bytecode translation starts here");
        // Generate bytecode
        for (offset, bytecode) in code.iter().enumerate() {
            self.translate_bytecode(func_target, &context, offset as CodeOffset, bytecode);
        }
        // Generate abort exit.
        let end_loc = func_target.get_loc().at_end();
        self.writer.set_location(&end_loc);
        self.writer.unindent();
        emitln!(self.writer, "Abort:");
        self.writer.indent();
        emitln!(self.writer, "$abort_flag := true;");
        emitln!(self.writer, "$m := $saved_m;");
        for (i, ty) in func_target.get_return_types().iter().enumerate() {
            let ret_str = format!("$ret{}", i);
            if ty.is_reference() {
                emitln!(self.writer, "{} := $DefaultReference;", &ret_str);
            } else {
                emitln!(self.writer, "{} := $DefaultValue();", &ret_str);
            }
        }
        self.writer.unindent();
        emitln!(self.writer, "}");
    }
fn generate_inline_function_body ( & self , func_target : & FunctionTarget < ' _ > ) { let code = func_target . get_bytecode ( ) ; // Construct context for bytecode translation. let mut context = BytecodeContext :: default ( ) ; // Walk over the bytecode and collect various context information. for bytecode in code { match bytecode { Call ( _ , dsts , oper , _ ) => { use Operation :: * ; match oper { BorrowLoc | BorrowGlobal ( .. ) | BorrowField ( .. ) => { let dst = dsts [ 0 ] ; let ty = func_target . get_local_type ( dst ) ; if ty . is_mutable_reference ( ) { // Track that we create a mutable reference here. context . mutable_refs . insert ( dst ) ; } } _ => { } } } Assign ( _ , dst , src , AssignKind :: Move ) | Assign ( _ , dst , src , AssignKind :: Store ) => { // Propagate information from src to dst. if context . mutable_refs . contains ( src ) { context . mutable_refs . insert ( * dst ) ; } } _ => { } } } // Be sure to set back location to the whole function definition as a default, otherwise // we may get unassigned code locations associated with condition locations. self . writer . set_location ( & func_target . get_loc ( ) ) ; emitln ! ( self writer " " ) ; self . writer . indent ( ) ; // Generate local variable declarations. They need to appear first in boogie. emitln ! ( self writer " " ) ; let num_args = func_target . get_parameter_count ( ) ; for i in num_args .. func_target . get_local_count ( ) { let local_name = func_target . get_local_name ( i ) ; let local_type = func_target . get_local_type ( i ) ; emitln ! ( self writer " " local_name display ( func_target symbol_pool ( ) ) boogie_local_type ( local_type ) boogie_type_value ( self module_env env local_type ) ) ; } emitln ! ( self writer " " ) ; emitln ! ( self writer " " ) ; emitln ! ( self writer " \n " ) ; emitln ! ( self writer " " ) ; emitln ! ( self writer " " ) ; emitln ! ( self writer " \n " ) ; // Generate bytecode for ( offset , bytecode ) in code . iter ( ) . enumerate ( ) { self . translate_bytecode ( func_target , & context , offset as CodeOffset , bytecode ) ; } // Generate abort exit. let end_loc = func_target . get_loc ( ) . at_end ( ) ; self . writer . set_location ( & end_loc ) ; self . writer . unindent ( ) ; emitln ! ( self writer " " ) ; self . writer . indent ( ) ; emitln ! ( self writer " " ) ; emitln ! ( self writer " " ) ; for ( i , ty ) in func_target . get_return_types ( ) . iter ( ) . enumerate ( ) { let ret_str = format ! ( " " i ) ; if ty . is_reference ( ) { emitln ! ( self writer " " ret_str ) ; } else { emitln ! ( self writer " " ret_str ) ; } } self . writer . unindent ( ) ; emitln ! ( self writer " " ) ; }
This generates boogie code for everything after the function signature
The function body is only generated for the "inline" version of the function.
This generates boogie code for everything after the function signature The function body is only generated for the " inline " version of the function .
&self
func_target
&FunctionTarget<'_>
&self
func_target
&FunctionTarget<'_>