summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/op_string.go52
-rw-r--r--vm/vm.go18
2 files changed, 43 insertions, 27 deletions
diff --git a/vm/op_string.go b/vm/op_string.go
index ac5b557..63bf738 100644
--- a/vm/op_string.go
+++ b/vm/op_string.go
@@ -20,34 +20,36 @@ func _() {
_ = x[Deref-9]
_ = x[Dup-10]
_ = x[Fdup-11]
- _ = x[Equal-12]
- _ = x[EqualSet-13]
- _ = x[Exit-14]
- _ = x[Field-15]
- _ = x[Greater-16]
- _ = x[Grow-17]
- _ = x[Index-18]
- _ = x[Jump-19]
- _ = x[JumpTrue-20]
- _ = x[JumpFalse-21]
- _ = x[JumpSetTrue-22]
- _ = x[JumpSetFalse-23]
- _ = x[Lower-24]
- _ = x[Loweri-25]
- _ = x[Mul-26]
- _ = x[New-27]
- _ = x[Not-28]
- _ = x[Pop-29]
- _ = x[Push-30]
- _ = x[Return-31]
- _ = x[Sub-32]
- _ = x[Subi-33]
- _ = x[Swap-34]
+ _ = x[Fnew-12]
+ _ = x[Equal-13]
+ _ = x[EqualSet-14]
+ _ = x[Exit-15]
+ _ = x[Field-16]
+ _ = x[FieldSet-17]
+ _ = x[Greater-18]
+ _ = x[Grow-19]
+ _ = x[Index-20]
+ _ = x[Jump-21]
+ _ = x[JumpTrue-22]
+ _ = x[JumpFalse-23]
+ _ = x[JumpSetTrue-24]
+ _ = x[JumpSetFalse-25]
+ _ = x[Lower-26]
+ _ = x[Loweri-27]
+ _ = x[Mul-28]
+ _ = x[New-29]
+ _ = x[Not-30]
+ _ = x[Pop-31]
+ _ = x[Push-32]
+ _ = x[Return-33]
+ _ = x[Sub-34]
+ _ = x[Subi-35]
+ _ = x[Swap-36]
}
-const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupEqualEqualSetExitFieldGreaterGrowIndexJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNotPopPushReturnSubSubiSwap"
+const _Op_name = "NopAddAddrAssignFassignVassignCallCalliCallXDerefDupFdupFnewEqualEqualSetExitFieldFieldSetGreaterGrowIndexJumpJumpTrueJumpFalseJumpSetTrueJumpSetFalseLowerLoweriMulNewNotPopPushReturnSubSubiSwap"
-var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 61, 69, 73, 78, 85, 89, 94, 98, 106, 115, 126, 138, 143, 149, 152, 155, 158, 161, 165, 171, 174, 178, 182}
+var _Op_index = [...]uint8{0, 3, 6, 10, 16, 23, 30, 34, 39, 44, 49, 52, 56, 60, 65, 73, 77, 82, 90, 97, 101, 106, 110, 118, 127, 138, 150, 155, 161, 164, 167, 170, 173, 177, 183, 186, 190, 194}
func (i Op) String() string {
idx := int(i) - 0
diff --git a/vm/vm.go b/vm/vm.go
index 7afe374..d035226 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -31,10 +31,12 @@ const (
Deref // x -- *x ;
Dup // addr -- value ; value = mem[addr]
Fdup // addr -- value ; value = mem[addr]
+ Fnew // -- x; x = new mem[$1]
Equal // n1 n2 -- cond ; cond = n1 == n2
EqualSet // n1 n2 -- n1 cond ; cond = n1 == n2
Exit // -- ;
Field // s -- f ; f = s.FieldIndex($1, ...)
+ FieldSet // s d -- s ; s.FieldIndex($1, ...) = d
Greater // n1 n2 -- cond; cond = n1 > n2
Grow // -- ; sp += $1
Index // a i -- a[i] ;
@@ -98,7 +100,7 @@ func (m *Machine) Run() (err error) {
sp = len(mem) // stack pointer
c := m.code[ip]
if debug {
- log.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-14v] mem:%v\n", ip, sp, fp, c, Vstring(mem))
+ log.Printf("ip:%-4d sp:%-4d fp:%-4d op:[%-18v] mem:%v\n", ip, sp, fp, c, Vstring(mem))
}
ic++
switch c.Op {
@@ -160,6 +162,8 @@ func (m *Machine) Run() (err error) {
return err
case Fdup:
mem = append(mem, mem[c.Arg[0]+fp-1])
+ case Fnew:
+ mem = append(mem, NewValue(mem[c.Arg[0]].Type))
case Field:
fv := mem[sp-1].FieldByIndex(c.Arg)
if !fv.CanSet() {
@@ -167,6 +171,15 @@ func (m *Machine) Run() (err error) {
fv = reflect.NewAt(fv.Type(), unsafe.Pointer(fv.UnsafeAddr())).Elem()
}
mem[sp-1].Value = fv
+ case FieldSet:
+ fv := mem[sp-1].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()
+ }
+ fv.Set(mem[sp-2].Value)
+ mem[sp-2] = mem[sp-1]
+ mem = mem[:sp-1]
case Jump:
ip += c.Arg[0]
continue
@@ -229,7 +242,8 @@ func (m *Machine) Run() (err error) {
case Subi:
mem[sp-1] = ValueOf(int(mem[sp-1].Int()) - c.Arg[0])
case Swap:
- mem[sp-2], mem[sp-1] = mem[sp-1], mem[sp-2]
+ a, b := sp-c.Arg[0]-1, sp-c.Arg[1]-1
+ mem[a], mem[b] = mem[b], mem[a]
case Index:
mem[sp-2].Value = mem[sp-1].Index(int(mem[sp-2].Int()))
mem = mem[:sp-1]