Exemplo n.º 1
0
func toSSA(src io.Reader, file, pkg string) (SSA, error) {
	var fs []Func
	var conf loader.Config

	// Parse the file into a ssa file
	f, _ := conf.ParseFile(file, src)
	conf.CreateFromFiles("main.go", f)
	p, _ := conf.Load()
	buildsanity := content["ssabuild"] == true
	var ssap *ssa.Program
	if buildsanity {
		ssap = ssautil.CreateProgram(p, ssa.SanityCheckFunctions)
	} else {
		ssap = ssautil.CreateProgram(p, ssa.NaiveForm)
	}

	// Build ssa prog to retrieve all information and the main pkg
	ssap.Build()
	mainpkg := ssap.Package(p.InitialPackages()[0].Pkg)

	for _, m := range mainpkg.Members {
		if m.Token() == token.FUNC {
			f, ok := m.(*ssa.Function)
			if ok {
				var params []Value
				for _, p := range f.Params {
					v := Value{p.Name(), reflect.TypeOf(p).String()}
					params = append(params, v)
				}
				var freevars []Value
				for _, fv := range f.FreeVars {
					v := Value{fv.Name(), reflect.TypeOf(fv).String()}
					freevars = append(freevars, v)
				}
				var locals []Value
				for _, l := range f.Locals {
					v := Value{l.Name(), reflect.TypeOf(l).String()}
					locals = append(locals, v)
				}
				var blocks []BB
				for _, b := range f.Blocks {
					var instrs []Instr
					for _, i := range b.Instrs {
						in := Instr{i.String(), reflect.TypeOf(i).String()}
						instrs = append(instrs, in)
					}
					var preds []int
					for _, p := range b.Preds {
						preds = append(preds, p.Index)
					}
					var succs []int
					for _, s := range b.Succs {
						succs = append(succs, s.Index)
					}
					bb := BB{b.Index, instrs, preds, succs}
					blocks = append(blocks, bb)
				}
				fn := Func{f.Name(), params, "par_" + f.Name(), freevars, "freevars_" + f.Name(), locals, "locals_" + f.Name(), blocks, "blocks_" + f.Name()}
				fs = append(fs, fn)
			}
		}
	}
	return SSA{fs}, nil
}