diff options
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/type.go | 11 | ||||
| -rw-r--r-- | vm/vm.go | 8 |
2 files changed, 15 insertions, 4 deletions
@@ -6,12 +6,16 @@ import "reflect" // Type is the representation of a runtime type. type Type struct { - Name string - Rtype reflect.Type + PkgPath string + Name string + Rtype reflect.Type } func (t *Type) String() string { if t.Name != "" { + if t.PkgPath != "" { + return t.PkgPath + "." + t.Name + } return t.Name } return t.Rtype.String() @@ -84,7 +88,8 @@ func FuncOf(arg, ret []*Type, variadic bool) *Type { func StructOf(fields []*Type) *Type { rf := make([]reflect.StructField, len(fields)) for i, f := range fields { - rf[i].Name = "X" + f.Name + rf[i].Name = f.Name + rf[i].PkgPath = f.PkgPath rf[i].Type = f.Rtype } return &Type{Rtype: reflect.StructOf(rf)} @@ -6,6 +6,7 @@ import ( "log" // for tracing only "reflect" // for optional CallX only "strconv" // for tracing only + "unsafe" // to allow setting unexported struct fields ) const debug = true @@ -184,7 +185,12 @@ func (m *Machine) Run() (err error) { case Fdup: mem = append(mem, mem[int(op[2])+fp-1]) case Field: - mem[sp-1].Data = mem[sp-1].Data.FieldByIndex(slint(op[2:])) + fv := mem[sp-1].Data.FieldByIndex(slint(op[2:])) + if !fv.CanSet() { + // Normally private fields can not bet set via reflect. Override this limitation. + fv = reflect.NewAt(fv.Type(), unsafe.Pointer(fv.UnsafeAddr())).Elem() + } + mem[sp-1].Data = fv case Jump: ip += int(op[2]) continue |
