コード例 #1
0
ファイル: eval.go プロジェクト: rocky/ssa-interp
func EnvLookup(fr *interp.Frame, name string,
	scope *ssa2.Scope) (ssa2.Value, interp.Value, *ssa2.Scope) {
	fn := fr.Fn()
	reg := fr.Var2Reg[name]
	for ; scope != nil; scope = ssa2.ParentScope(fn, scope) {
		nameScope := ssa2.NameScope{
			Name:  name,
			Scope: scope,
		}
		if i := fn.LocalsByName[nameScope]; i > 0 {
			nameVal := fn.Locals[i-1]
			val := fr.Env()[nameVal]
			return nameVal, val, nameVal.Scope
		}
	}
	names := []string{name, reg}
	for _, name := range names {
		for nameVal, val := range fr.Env() {
			if name == nameVal.Name() {
				switch nameVal := nameVal.(type) {
				case *ssa2.Alloc:
					return nameVal, val, nameVal.Scope
				default:
					return nameVal, val, nil
				}
			}
		}
	}
	// FIXME: Why we would find things here and not by the
	// above scope lookup?
	if val := fn.Pkg.Var(name); val != nil {
		return val, nil, nil
	}
	return nil, nil, nil
}
コード例 #2
0
ファイル: location.go プロジェクト: rocky/ssa-interp
func printLocInfo(fr *interp.Frame, inst *ssa2.Instruction,
	event ssa2.TraceEvent) {
	defer func() {
		if x := recover(); x != nil {
			Errmsg("Internal error in getting location info")
			debug.PrintStack()
		}
	}()
	s := Event2Icon[event] + " "
	fn := fr.Fn()
	sig := fn.Signature
	name := fn.Name()

	if fn.Signature.Recv() != nil {
		if len(fn.Params) == 0 {
			panic("Receiver method " + name + " should have at least 1 param. Has 0.")
		}
		s += fmt.Sprintf("(%s).%s()", fn.Params[0].Type(), name)
	} else {
		s += fmt.Sprintf("%s.%s", fn.Pkg.Object.Path(), name)
		if len(name) > 0 {
			s += "()"
		}
	}

	if *terse && (event != ssa2.STEP_INSTRUCTION) {
		Msg(s)
	} else {
		Msg("%s block %d insn %d", s, fr.Block().Index, fr.PC())
	}

	var syntax ast.Node = nil

	switch event {
	case ssa2.CALL_RETURN:
		if sig.Results() == nil {
			Msg("return void")
		} else {
			Msg("return type: %s", sig.Results())
			Msg("return value: %s", Deref2Str(fr.Result(), nil))
		}
	case ssa2.CALL_ENTER:
		syntax = fn.Syntax()
		for _, p := range fn.Params {
			if val := fr.Env()[p]; val != nil {
				ssaVal := ssa2.Value(p)
				Msg("%s %s", p, Deref2Str(val, &ssaVal))
			} else {
				Msg("%s nil", p)
			}
		}
	case ssa2.PANIC:
		// fmt.Printf("panic arg: %s\n", fr.Get(instr.X))
	}

	Msg(fr.PositionRange())
	if Instr != nil {
		switch s := (*Instr).(type) {
		case *ssa2.Trace:
			syntax = s.Syntax()
		}
		if syntax != nil {
			PrintSyntaxFirstLine(syntax, fn.Prog.Fset)
		}
	}
}