func()

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
}