Пример #1
0
// Go handles Go statements.
func (caller *Function) Go(instr *ssa.Go, infer *TypeInfer) {
	common := instr.Common()
	callee := caller.prepareCallFn(common, common.StaticCallee(), nil)
	spawnStmt := &migo.SpawnStatement{Name: callee.Fn.String(), Params: []*migo.Parameter{}}
	for i, c := range common.Args {
		if _, ok := c.Type().(*types.Chan); ok {
			ch := getChan(c, infer)
			spawnStmt.AddParams(&migo.Parameter{Caller: ch, Callee: callee.Fn.Params[i]})
		}
	}
	if inst, ok := caller.locals[common.Value]; ok {
		if bindings, ok := caller.Prog.closures[inst]; ok {
			for _, b := range bindings {
				if v, ok := b.(*Value); ok {
					if _, ok := derefType(v.Type()).(*types.Chan); ok {
						spawnStmt.AddParams(&migo.Parameter{Caller: v, Callee: v})
					}
				}
			}
		}
	}
	caller.FuncDef.AddStmts(spawnStmt)
	// Don't actually call/visit the function but enqueue it.
	infer.GQueue = append(infer.GQueue, callee)
}
Пример #2
0
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)
}