func (caller *frame) callGo(g *ssa.Go) { common := g.Common() goname := fmt.Sprintf("%s_%d", common.Value.Name(), int(g.Pos())) gorole := caller.env.session.GetRole(goname) callee := &frame{ fn: common.StaticCallee(), locals: make(map[ssa.Value]*utils.Definition), arrays: make(map[*utils.Definition]Elems), structs: make(map[*utils.Definition]Fields), tuples: make(map[ssa.Value]Tuples), phi: make(map[ssa.Value][]ssa.Value), recvok: make(map[ssa.Value]*sesstype.Chan), retvals: make(Tuples, common.Signature().Results().Len()), defers: make([]*ssa.Defer, 0), caller: caller, env: caller.env, // Use the same env as caller gortn: &goroutine{ role: gorole, root: sesstype.NewLabelNode(goname), leaf: nil, visited: make(map[*ssa.BasicBlock]sesstype.Node), }, } callee.gortn.leaf = &callee.gortn.root fmt.Fprintf(os.Stderr, "@@ queue go %s(", common.StaticCallee().String()) callee.translate(common) fmt.Fprintf(os.Stderr, ")\n") // TODO(nickng) Does not stop at recursive call. caller.env.extract.goQueue = append(caller.env.extract.goQueue, callee) }
func visitBlock(blk *ssa.BasicBlock, fr *frame) { if len(blk.Preds) > 1 { blkLabel := fmt.Sprintf("%s#%d", blk.Parent().String(), blk.Index) if _, found := fr.gortn.visited[blk]; found { fr.gortn.AddNode(sesstype.NewGotoNode(blkLabel)) return } // Make a label for other edges that enter this block label := sesstype.NewLabelNode(blkLabel) fr.gortn.AddNode(label) fr.gortn.visited[blk] = label // XXX visited is initialised by append if lblNode is head of tree } for _, inst := range blk.Instrs { visitInst(inst, fr) } }
func makeToplevelFrame(extract *CFSMExtract) *frame { callee := &frame{ fn: nil, locals: make(map[ssa.Value]*utils.Definition), arrays: make(map[*utils.Definition]Elems), structs: make(map[*utils.Definition]Fields), tuples: make(map[ssa.Value]Tuples), phi: make(map[ssa.Value][]ssa.Value), recvok: make(map[ssa.Value]*sesstype.Chan), retvals: make(Tuples, 0), defers: make([]*ssa.Defer, 0), caller: nil, env: &environ{ session: extract.session, extract: extract, globals: make(map[ssa.Value]*utils.Definition), arrays: make(map[*utils.Definition]Elems), structs: make(map[*utils.Definition]Fields), chans: make(map[*utils.Definition]*sesstype.Chan), extern: make(map[ssa.Value]types.Type), closures: make(map[ssa.Value]Captures), selNode: make(map[ssa.Value]struct { parent *sesstype.Node blocking bool }), selIdx: make(map[ssa.Value]ssa.Value), selTest: make(map[ssa.Value]struct { idx int tpl ssa.Value }), recvTest: make(map[ssa.Value]*sesstype.Chan), ifparent: sesstype.NewNodeStack(), }, gortn: &goroutine{ role: extract.session.GetRole("main"), root: sesstype.NewLabelNode("main"), leaf: nil, visited: make(map[*ssa.BasicBlock]sesstype.Node), }, } callee.gortn.leaf = &callee.gortn.root return callee }