|
@@ -6,6 +6,7 @@ import (
|
|
|
"math"
|
|
|
"strconv"
|
|
|
"sync"
|
|
|
+ "sync/atomic"
|
|
|
)
|
|
|
|
|
|
const (
|
|
@@ -111,7 +112,7 @@ type vm struct {
|
|
|
stashAllocs int
|
|
|
halt bool
|
|
|
|
|
|
- interrupt bool
|
|
|
+ interrupted uint32
|
|
|
interruptVal interface{}
|
|
|
interruptLock sync.Mutex
|
|
|
}
|
|
@@ -277,16 +278,20 @@ func (vm *vm) init() {
|
|
|
|
|
|
func (vm *vm) run() {
|
|
|
vm.halt = false
|
|
|
- for !vm.halt && !vm.interrupt {
|
|
|
+ interrupted := false
|
|
|
+ for !vm.halt {
|
|
|
+ if interrupted = atomic.LoadUint32(&vm.interrupted) != 0; interrupted {
|
|
|
+ break
|
|
|
+ }
|
|
|
vm.prg.code[vm.pc].exec(vm)
|
|
|
}
|
|
|
|
|
|
- if vm.interrupt {
|
|
|
+ if interrupted {
|
|
|
vm.interruptLock.Lock()
|
|
|
v := &InterruptedError{
|
|
|
iface: vm.interruptVal,
|
|
|
}
|
|
|
- vm.interrupt = false
|
|
|
+ atomic.StoreUint32(&vm.interrupted, 0)
|
|
|
vm.interruptVal = nil
|
|
|
vm.interruptLock.Unlock()
|
|
|
panic(v)
|
|
@@ -296,7 +301,7 @@ func (vm *vm) run() {
|
|
|
func (vm *vm) Interrupt(v interface{}) {
|
|
|
vm.interruptLock.Lock()
|
|
|
vm.interruptVal = v
|
|
|
- vm.interrupt = true
|
|
|
+ atomic.StoreUint32(&vm.interrupted, 1)
|
|
|
vm.interruptLock.Unlock()
|
|
|
}
|
|
|
|