proc/variable: changed Value's type to constant.Value

This commit is contained in:
aarzilli 2015-10-21 09:06:36 +02:00 committed by Derek Parker
parent 50b5fc92e2
commit d65e832524
4 changed files with 53 additions and 28 deletions

@ -5,6 +5,7 @@ import (
"debug/gosym" "debug/gosym"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -707,7 +708,7 @@ func (dbp *Process) getGoInformation() (ver GoVersion, isextld bool, err error)
return return
} }
ver, ok := parseVersionString(vv.Value.(string)) ver, ok := parseVersionString(constant.StringVal(vv.Value))
if !ok { if !ok {
err = fmt.Errorf("Could not parse version number: %v\n", vv.Value) err = fmt.Errorf("Could not parse version number: %v\n", vv.Value)
return return

@ -3,6 +3,7 @@ package proc
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"go/constant"
"net" "net"
"net/http" "net/http"
"os" "os"
@ -317,6 +318,7 @@ func TestNextConcurrent(t *testing.T) {
assertNoError(p.Continue(), t, "Continue") assertNoError(p.Continue(), t, "Continue")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
initV, err := evalVariable(p, "n") initV, err := evalVariable(p, "n")
initVval, _ := constant.Int64Val(initV.Value)
assertNoError(err, t, "EvalVariable") assertNoError(err, t, "EvalVariable")
for _, tc := range testcases { for _, tc := range testcases {
g, err := p.CurrentThread.GetG() g, err := p.CurrentThread.GetG()
@ -334,7 +336,8 @@ func TestNextConcurrent(t *testing.T) {
} }
v, err := evalVariable(p, "n") v, err := evalVariable(p, "n")
assertNoError(err, t, "EvalVariable") assertNoError(err, t, "EvalVariable")
if v.Value.(int64) != initV.Value.(int64) { vval, _ := constant.Int64Val(v.Value)
if vval != initVval {
t.Fatal("Did not end up on same goroutine") t.Fatal("Did not end up on same goroutine")
} }
} }
@ -877,17 +880,19 @@ func TestVariableEvaluation(t *testing.T) {
if v.Value == nil && tc.value != nil { if v.Value == nil && tc.value != nil {
t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value) t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value)
} else { } else {
switch x := v.Value.(type) { switch v.Kind {
case int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
x, _ := constant.Int64Val(v.Value)
if y, ok := tc.value.(int64); !ok || x != y { if y, ok := tc.value.(int64); !ok || x != y {
t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value) t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value)
} }
case float64: case reflect.Float32, reflect.Float64:
x, _ := constant.Float64Val(v.Value)
if y, ok := tc.value.(float64); !ok || x != y { if y, ok := tc.value.(float64); !ok || x != y {
t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value) t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value)
} }
case string: case reflect.String:
if y, ok := tc.value.(string); !ok || x != y { if y, ok := tc.value.(string); !ok || constant.StringVal(v.Value) != y {
t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value) t.Fatalf("%s value: expected: %v got: %v", tc.name, tc.value, v.Value)
} }
} }
@ -940,7 +945,8 @@ func TestFrameEvaluation(t *testing.T) {
t.Logf("Goroutine %d: %v\n", g.Id, err) t.Logf("Goroutine %d: %v\n", g.Id, err)
continue continue
} }
found[v.Value.(int64)] = true vval, _ := constant.Int64Val(v.Value)
found[vval] = true
} }
for i := range found { for i := range found {
@ -959,7 +965,7 @@ func TestFrameEvaluation(t *testing.T) {
assertNoError(err, t, fmt.Sprintf("ConvertEvalScope() on frame %d", i+1)) assertNoError(err, t, fmt.Sprintf("ConvertEvalScope() on frame %d", i+1))
v, err := scope.EvalVariable("n") v, err := scope.EvalVariable("n")
assertNoError(err, t, fmt.Sprintf("EvalVariable() on frame %d", i+1)) assertNoError(err, t, fmt.Sprintf("EvalVariable() on frame %d", i+1))
n := v.Value.(int64) n, _ := constant.Int64Val(v.Value)
t.Logf("frame %d n %d\n", i+1, n) t.Logf("frame %d n %d\n", i+1, n)
if n != int64(3-i) { if n != int64(3-i) {
t.Fatalf("On frame %d value of n is %d (not %d)", i+1, n, 3-i) t.Fatalf("On frame %d value of n is %d (not %d)", i+1, n, 3-i)
@ -975,8 +981,9 @@ func TestPointerSetting(t *testing.T) {
pval := func(n int64) { pval := func(n int64) {
variable, err := evalVariable(p, "p1") variable, err := evalVariable(p, "p1")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
if variable.Children[0].Value.(int64) != n { c0val, _ := constant.Int64Val(variable.Children[0].Value)
t.Fatalf("Wrong value of p1, *%d expected *%d", variable.Children[0].Value.(int64), n) if c0val != n {
t.Fatalf("Wrong value of p1, *%d expected *%d", c0val, n)
} }
} }

@ -6,6 +6,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/ast" "go/ast"
"go/constant"
"go/parser" "go/parser"
"go/token" "go/token"
"reflect" "reflect"
@ -35,7 +36,7 @@ type Variable struct {
Kind reflect.Kind Kind reflect.Kind
thread *Thread thread *Thread
Value interface{} Value constant.Value
Len int64 Len int64
Cap int64 Cap int64
@ -681,7 +682,9 @@ func (v *Variable) loadValueInternal(recurseLevel int) {
v.Children[0].loadValueInternal(recurseLevel) v.Children[0].loadValueInternal(recurseLevel)
case reflect.String: case reflect.String:
v.Value, v.Len, v.Unreadable = v.thread.readString(uintptr(v.Addr)) var val string
val, v.Len, v.Unreadable = v.thread.readString(uintptr(v.Addr))
v.Value = constant.MakeString(val)
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
v.loadArrayValues(recurseLevel) v.loadArrayValues(recurseLevel)
@ -704,17 +707,24 @@ func (v *Variable) loadValueInternal(recurseLevel int) {
case reflect.Complex64, reflect.Complex128: case reflect.Complex64, reflect.Complex128:
v.readComplex(v.RealType.(*dwarf.ComplexType).ByteSize) v.readComplex(v.RealType.(*dwarf.ComplexType).ByteSize)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v.Value, v.Unreadable = v.thread.readIntRaw(v.Addr, v.RealType.(*dwarf.IntType).ByteSize) var val int64
val, v.Unreadable = v.thread.readIntRaw(v.Addr, v.RealType.(*dwarf.IntType).ByteSize)
v.Value = constant.MakeInt64(val)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
v.Value, v.Unreadable = v.thread.readUintRaw(v.Addr, v.RealType.(*dwarf.UintType).ByteSize) var val uint64
val, v.Unreadable = v.thread.readUintRaw(v.Addr, v.RealType.(*dwarf.UintType).ByteSize)
v.Value = constant.MakeUint64(val)
case reflect.Bool: case reflect.Bool:
val, err := v.thread.readMemory(v.Addr, 1) val, err := v.thread.readMemory(v.Addr, 1)
v.Unreadable = err v.Unreadable = err
if err == nil { if err == nil {
v.Value = val[0] != 0 v.Value = constant.MakeBool(val[0] != 0)
} }
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
v.Value, v.Unreadable = v.readFloatRaw(v.RealType.(*dwarf.FloatType).ByteSize) var val float64
val, v.Unreadable = v.readFloatRaw(v.RealType.(*dwarf.FloatType).ByteSize)
v.Value = constant.MakeFloat64(val)
case reflect.Func: case reflect.Func:
v.readFunctionPtr() v.readFunctionPtr()
case reflect.Map: case reflect.Map:
@ -804,14 +814,14 @@ func (v *Variable) loadSliceInfo(t *dwarf.StructType) {
lstrAddr.loadValue() lstrAddr.loadValue()
err = lstrAddr.Unreadable err = lstrAddr.Unreadable
if err == nil { if err == nil {
v.Len = lstrAddr.Value.(int64) v.Len, _ = constant.Int64Val(lstrAddr.Value)
} }
case "cap": case "cap":
cstrAddr, _ := v.toField(f) cstrAddr, _ := v.toField(f)
cstrAddr.loadValue() cstrAddr.loadValue()
err = cstrAddr.Unreadable err = cstrAddr.Unreadable
if err == nil { if err == nil {
v.Cap = cstrAddr.Value.(int64) v.Cap, _ = constant.Int64Val(cstrAddr.Value)
} }
} }
if err != nil { if err != nil {
@ -875,6 +885,7 @@ func (v *Variable) readComplex(size int64) {
imagvar.loadValue() imagvar.loadValue()
v.Len = 2 v.Len = 2
v.Children = []Variable{*realvar, *imagvar} v.Children = []Variable{*realvar, *imagvar}
v.Value = constant.BinaryOp(realvar.Value, token.ADD, imagvar.Value)
} }
func (v *Variable) writeComplex(value string, size int64) error { func (v *Variable) writeComplex(value string, size int64) error {
@ -1114,7 +1125,7 @@ func (v *Variable) readFunctionPtr() {
return return
} }
v.Value = fn.Name v.Value = constant.MakeString(fn.Name)
} }
// Fetches all variables of a specific type in the current function scope // Fetches all variables of a specific type in the current function scope

@ -1,9 +1,9 @@
package api package api
import ( import (
"debug/dwarf"
"debug/gosym" "debug/gosym"
"fmt" "go/constant"
"reflect"
"strconv" "strconv"
"github.com/derekparker/delve/proc" "github.com/derekparker/delve/proc"
@ -80,12 +80,18 @@ func ConvertVar(v *proc.Variable) *Variable {
r.Unreadable = v.Unreadable.Error() r.Unreadable = v.Unreadable.Error()
} }
switch typ := v.RealType.(type) { if v.Value != nil {
case *dwarf.FloatType: switch v.Kind {
r.Value = strconv.FormatFloat(v.Value.(float64), 'f', -1, int(typ.Size()*8)) case reflect.Float32:
default: f, _ := constant.Float64Val(v.Value)
if v.Value != nil { r.Value = strconv.FormatFloat(f, 'f', -1, 32)
r.Value = fmt.Sprintf("%v", v.Value) case reflect.Float64:
f, _ := constant.Float64Val(v.Value)
r.Value = strconv.FormatFloat(f, 'f', -1, 64)
case reflect.String, reflect.Func:
r.Value = constant.StringVal(v.Value)
default:
r.Value = v.Value.String()
} }
} }