in tool/instrument/optimize.go [172:210]
func (rp *RuleProcessor) removeOnEnterTrampolineCall(tjump *TJump) error {
// Construct CallContext on the fly and pass to onExit trampoline defer call
callContextExpr, err := rp.newCallContextImpl(tjump)
if err != nil {
return err
}
// Find defer call to onExit and replace its call context with new one
found := false
for _, stmt := range tjump.ifStmt.Else.(*dst.BlockStmt).List {
// Replace call context argument of defer statement to structure literal
if deferStmt, ok := stmt.(*dst.DeferStmt); ok {
args := deferStmt.Call.Args
util.Assert(len(args) >= 1, "must have at least one argument")
args[0] = callContextExpr
found = true
break
}
}
util.Assert(found, "defer statement not found")
// Rewrite condition of trampoline-jump-if to always false and null out its
// initialization statement and then block
tjump.ifStmt.Init = nil
tjump.ifStmt.Cond = util.BoolFalse()
tjump.ifStmt.Body = util.Block(util.EmptyStmt())
if config.GetConf().Verbose {
util.Log("Optimize tjump branch in %s", tjump.target.Name.Name)
}
// Remove generated onEnter trampoline function
removed := rp.removeDeclWhen(func(d dst.Decl) bool {
if funcDecl, ok := d.(*dst.FuncDecl); ok {
return funcDecl.Name.Name == rp.makeName(tjump.rule, tjump.target, true)
}
return false
})
if removed == nil {
return errc.New(errc.ErrInternal, "onEnter trampoline not found")
}
return nil
}