// Run function analyses main.main() then all the goroutines collected, and // finally output the analysis results. func (extract *CFSMExtract) Run() { startTime := time.Now() mainPkg := ssabuilder.MainPkg(extract.SSA.Prog) if mainPkg == nil { fmt.Fprintf(os.Stderr, "Error: 'main' package not found\n") os.Exit(1) } init := mainPkg.Func("init") main := mainPkg.Func("main") fr := makeToplevelFrame(extract) for _, pkg := range extract.SSA.Prog.AllPackages() { for _, memb := range pkg.Members { switch val := memb.(type) { case *ssa.Global: switch derefAll(val.Type()).(type) { case *types.Array: vd := utils.NewDef(val) fr.env.globals[val] = vd fr.env.arrays[vd] = make(Elems) case *types.Struct: vd := utils.NewDef(val) fr.env.globals[val] = vd fr.env.structs[vd] = make(Fields) case *types.Chan: var c *types.Chan vd := utils.NewDef(utils.EmptyValue{T: c}) fr.env.globals[val] = vd default: fr.env.globals[val] = utils.NewDef(val) } } } } fmt.Fprintf(os.Stderr, "++ call.toplevel %s()\n", orange("init")) visitFunc(init, fr) if main == nil { fmt.Fprintf(os.Stderr, "Error: 'main()' function not found in 'main' package\n") os.Exit(1) } fmt.Fprintf(os.Stderr, "++ call.toplevel %s()\n", orange("main")) visitFunc(main, fr) fr.env.session.Types[fr.gortn.role] = fr.gortn.root var goFrm *frame for len(extract.goQueue) > 0 { goFrm, extract.goQueue = extract.goQueue[0], extract.goQueue[1:] fmt.Fprintf(os.Stderr, "\n%s\nLOCATION: %s%s\n", goFrm.fn.Name(), goFrm.gortn.role.Name(), loc(goFrm, goFrm.fn.Pos())) visitFunc(goFrm.fn, goFrm) goFrm.env.session.Types[goFrm.gortn.role] = goFrm.gortn.root } extract.Time = time.Since(startTime) extract.Done <- struct{}{} }
// Run executes the analysis. func (infer *TypeInfer) Run() { infer.Logger.Println("---- Start Analysis ----") // Initialise session. infer.Env = NewProgram(infer) infer.Env.MigoProg = migo.NewProgram() startTime := time.Now() mainPkg := ssabuilder.MainPkg(infer.SSA.Prog) if mainPkg == nil { infer.Error <- ErrNoMainPkg } defer close(infer.Done) initFn := mainPkg.Func("init") mainFn := mainPkg.Func("main") ctx := NewMainFunction(infer.Env, mainFn) // TODO(nickng): inline initialisation of var declarations for _, pkg := range infer.SSA.Prog.AllPackages() { for _, memb := range pkg.Members { switch value := memb.(type) { case *ssa.Global: ctx.Prog.globals[value] = &Value{Value: value} switch t := derefAllType(value.Type()).Underlying().(type) { case *types.Array: ctx.Prog.arrays[ctx.Prog.globals[value]] = make(Elems, t.Len()) case *types.Slice: ctx.Prog.arrays[ctx.Prog.globals[value]] = make(Elems, 0) case *types.Struct: ctx.Prog.structs[ctx.Prog.globals[value]] = make(Fields, t.NumFields()) default: } } } } visitFunc(initFn, infer, ctx) visitFunc(mainFn, infer, ctx) infer.RunQueue() infer.Time = time.Now().Sub(startTime) }