summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/op_string.go64
-rw-r--r--vm/type.go3
-rw-r--r--vm/vm.go11
3 files changed, 47 insertions, 31 deletions
diff --git a/vm/op_string.go b/vm/op_string.go
index e838628..5542c6e 100644
--- a/vm/op_string.go
+++ b/vm/op_string.go
@@ -21,40 +21,42 @@ func _() {
_ = x[Dup-10]
_ = x[Fdup-11]
_ = x[Fnew-12]
- _ = x[Equal-13]
- _ = x[EqualSet-14]
- _ = x[Exit-15]
- _ = x[Field-16]
- _ = x[FieldSet-17]
- _ = x[FieldFset-18]
- _ = x[Greater-19]
- _ = x[Grow-20]
- _ = x[Index-21]
- _ = x[IndexSet-22]
- _ = x[MapIndex-23]
- _ = x[MapSet-24]
- _ = x[Jump-25]
- _ = x[JumpTrue-26]
- _ = x[JumpFalse-27]
- _ = x[JumpSetTrue-28]
- _ = x[JumpSetFalse-29]
- _ = x[Lower-30]
- _ = x[Loweri-31]
- _ = x[Mul-32]
- _ = x[New-33]
- _ = x[Negate-34]
- _ = x[Not-35]
- _ = x[Pop-36]
- _ = x[Push-37]
- _ = x[Return-38]
- _ = x[Sub-39]
- _ = x[Subi-40]
- _ = x[Swap-41]
+ _ = x[FnewE-13]
+ _ = x[Equal-14]
+ _ = x[EqualSet-15]
+ _ = x[Exit-16]
+ _ = x[Field-17]
+ _ = x[FieldE-18]
+ _ = x[FieldSet-19]
+ _ = x[FieldFset-20]
+ _ = x[Greater-21]
+ _ = x[Grow-22]
+ _ = x[Index-23]
+ _ = x[IndexSet-24]
+ _ = x[MapIndex-25]
+ _ = x[MapSet-26]
+ _ = x[Jump-27]
+ _ = x[JumpTrue-28]
+ _ = x[JumpFalse-29]
+ _ = x[JumpSetTrue-30]
+ _ = x[JumpSetFalse-31]
+ _ = x[Lower-32]
+ _ = x[Loweri-33]
+ _ = x[Mul-34]
+ _ = x[New-35]
+ _ = x[Negate-36]
+ _ = x[Not-37]
+ _ = x[Pop-38]
+ _ = x[Push-39]
+ _ = x[Return-40]
+ _ = x[Sub-41]
+ _ = x[Subi-42]
+ _ = x[Swap-43]
}
-const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewEqualEqualSetExitFieldFieldSetFieldFsetGreaterGrowIndexIndexSetMapIndexMapSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNegateNotPopPushReturnSubSubiSwap"
+const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewFnewEEqualEqualSetExitFieldFieldEFieldSetFieldFsetGreaterGrowIndexIndexSetMapIndexMapSetJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNegateNotPopPushReturnSubSubiSwap"
-var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 73, 77, 82, 90, 99, 106, 110, 115, 123, 131, 137, 141, 149, 158, 169, 181, 186, 192, 195, 198, 204, 207, 210, 214, 220, 223, 227, 231}
+var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 70, 78, 82, 87, 93, 101, 110, 117, 121, 126, 134, 142, 148, 152, 160, 169, 180, 192, 197, 203, 206, 209, 215, 218, 221, 225, 231, 234, 238, 242}
func (i Op) String() string {
idx := int(i) - 0
diff --git a/vm/type.go b/vm/type.go
index 88e3dc0..58b6c46 100644
--- a/vm/type.go
+++ b/vm/type.go
@@ -132,3 +132,6 @@ func (t *Type) FieldType(name string) *Type {
}
return nil
}
+
+// IsPtr returns true if type t is of pointer kind.
+func (t *Type) IsPtr() bool { return t.Rtype.Kind() == reflect.Pointer }
diff --git a/vm/vm.go b/vm/vm.go
index 2baf384..3f04bf6 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -32,10 +32,12 @@ const (
Dup // addr -- value ; value = mem[addr]
Fdup // addr -- value ; value = mem[addr]
Fnew // -- x; x = new mem[$1]
+ FnewE // -- x; x = new mem[$1].Elem()
Equal // n1 n2 -- cond ; cond = n1 == n2
EqualSet // n1 n2 -- n1 cond ; cond = n1 == n2
Exit // -- ;
Field // s -- f ; f = s.FieldIndex($1, ...)
+ FieldE // s -- f ; f = s.FieldIndex($1, ...)
FieldSet // s d -- s ; s.FieldIndex($1, ...) = d
FieldFset // s i v -- s; s.FieldIndex(i) = v
Greater // n1 n2 -- cond; cond = n1 > n2
@@ -173,6 +175,8 @@ func (m *Machine) Run() (err error) {
mem = append(mem, mem[c.Arg[0]+fp-1])
case Fnew:
mem = append(mem, NewValue(mem[c.Arg[0]].Type, c.Arg[1:]...))
+ case FnewE:
+ mem = append(mem, NewValue(mem[c.Arg[0]].Type.Elem(), c.Arg[1:]...))
case Field:
fv := mem[sp-1].FieldByIndex(c.Arg)
if !fv.CanSet() {
@@ -180,6 +184,13 @@ func (m *Machine) Run() (err error) {
fv = reflect.NewAt(fv.Type(), unsafe.Pointer(fv.UnsafeAddr())).Elem()
}
mem[sp-1].Value = fv
+ case FieldE:
+ fv := mem[sp-1].Value.Elem().FieldByIndex(c.Arg)
+ 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].Value = fv
case FieldSet:
fv := mem[sp-2].FieldByIndex(c.Arg)
if !fv.CanSet() {