func (v Value) FieldByName(name string) (Value, error) {
	st, ok := v.Type.(*StructType)
	if !ok {
		panic(fmt.Sprintf("bad type for Value.FieldByName(): %s (%T)", v.Type, v.Type))
	}
	f, ok := st.FieldByName(name)
	if !ok {
		return Value{}, fmt.Errorf("cannot find field %s in %s", name, st)
	}
	return v.Field(f)
}
FieldByName is a shorthand for v.Type.FieldByName followed by v.Field.
package corefile
import (
	"errors"
	"fmt"
	"math"
	"reflect"
)
var (
	ErrNil         = errors.New("nil pointer")
	ErrOutOfBounds = errors.New("access is out-of-bounds")
)
type Value struct {
	Type  Type
	Addr  uint64  
	Bytes []byte  
}
func (v Value) IsZero() bool {
	for _, b := range v.Bytes {
		if b != 0 {
			return false
		}
	}
	return true
}
func (v Value) Size() uint64 {
	return v.Type.Size()
}
func (v Value) ContainsAddress(addr uint64) bool {
	return v.Addr <= addr && addr < v.Addr+v.Type.Size()
}
func (v Value) Deref() (Value, error) {
	switch t := v.Type.(type) {
	case *PtrType:
		return v.Type.Program().Value(v.ReadScalar().(uint64), t.Elem)
	case *InterfaceType:
		if v.IsZero() {
			return Value{}, ErrNil
		}
		elemType, err := v.DynamicType()
		if err != nil {
			return Value{}, err
		}
		datafield := ifaceDataField
		if t.EFace {
			datafield = efaceDataField
		}
		v.Type = t.Rep
		if elemType.directIface() {
			data, err := v.Field(t.Rep.Fields[datafield])
			if err != nil {
				return Value{}, err
			}
			data.Type = elemType
			return data, nil
		} else {
			dataptr, err := v.Field(t.Rep.Fields[datafield])
			if err != nil {
				return Value{}, err
			}
			dataptr.Type = v.Type.Program().MakePtrType(elemType)
			return dataptr.Deref()
		}
	default:
		panic(fmt.Sprintf("bad type for Value.Deref(): %s (%T)", v.Type, v.Type))
	}
}
func (v Value) DynamicType() (Type, error) {
	t, ok := v.Type.(*InterfaceType)
	if !ok {
		return v.Type, nil
	}
	rep := t.Rep
	if t.EFace {
		v.Type = rep
		rtypePtr, err := v.Field(rep.Fields[efaceTypeField])
		if err != nil {
			return nil, err
		}
		return rep.Program().typeCache.convertRuntimeType(rtypePtr)
	} else {
		v.Type = rep
		itabPtr, err := v.Field(rep.Fields[ifaceTabField])
		if err != nil {
			return nil, err
		}
		return rep.Program().typeCache.convertRuntimeItab(itabPtr)
	}
}
func (v Value) typedSlice(offset uint64, t Type) (Value, error) {
	end := offset + t.Size()
	if end > v.Type.Size() {
		return Value{}, ErrOutOfBounds
	}
	return Value{
		Addr:  v.Addr + offset,
		Type:  t,
		Bytes: v.Bytes[offset:end:end],
	}, nil
}
func (v Value) Field(f StructField) (Value, error) {
	if _, ok := v.Type.(*StructType); !ok {
		panic(fmt.Sprintf("bad type for Value.Field(): %s (%T)", v.Type, v.Type))
	}
	v, err := v.typedSlice(f.Offset, f.Type)
	if err != nil {
		return Value{}, fmt.Errorf("error reading field %s.%s, type %s: %v", v.Type, f.Name, f.Type, err)
	}
	return v, nil
}