func frameInit(fr *interp.Frame) { topFrame = fr curFrame = fr frameIndex = 0 curBlock = fr.Block() // EvalEnv = interp.MakeEnv(EvalEnvironment(), program, fr) for stackSize = 0; fr != nil; fr = fr.Caller(0) { stackSize++ } switch TraceEvent { case ssa2.CALL_RETURN, ssa2.PROGRAM_TERMINATION: /* These guys are not in a basic block, so curFrame.Scope won't work here. . Not sure why fr.Fn() memory crashes either. Otherwise, I'd use fr.Fn().Scope */ curScope = nil /* A "block end" sets the frame block can be nil. There should be a better way to do this inside the interpreter but I get: panic: unexpected type: <nil>: <nil> when I tried it and don't know why. */ switch instr := (*Instr).(type) { case *ssa2.Return: if curBlock == nil { curBlock = instr.Block() } } default: // FIXME: may need other cases like defer_enter, panic, // block_end? curScope = curFrame.Scope() } }
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) } } }