status-go/geth/jail/jail_cell.go

75 lines
1.7 KiB
Go
Raw Normal View History

package jail
import (
"sync"
"github.com/robertkrimen/otto"
2017-09-01 22:17:34 +02:00
"github.com/status-im/ottoext/loop"
"github.com/status-im/ottoext/timers"
)
// Cell represents a single jail cell, which is basically a JavaScript VM.
type Cell struct {
sync.Mutex
id string
vm *otto.Otto
}
// newCell encapsulates what we need to create a new jailCell from the
// provided vm and eventloop instance.
func newCell(id string, vm *otto.Otto) (*Cell, error) {
2017-09-01 22:17:34 +02:00
// create new event loop for the new cell.
// this loop is handling 'setTimeout/setInterval'
// calls and is running endlessly in a separate goroutine
lo := loop.New(vm)
// register handlers for setTimeout/setInterval
// functions
if err := timers.Define(vm, lo); err != nil {
return nil, err
}
2017-09-01 22:17:34 +02:00
// finally, start loop in a goroutine
// Cell is currently immortal, so the loop
2017-09-01 22:17:34 +02:00
go lo.Run()
return &Cell{
id: id,
vm: vm,
}, nil
}
// Set sets the value to be keyed by the provided keyname.
func (cell *Cell) Set(key string, val interface{}) error {
cell.Lock()
defer cell.Unlock()
return cell.vm.Set(key, val)
}
// Get returns the giving key's otto.Value from the underline otto vm.
func (cell *Cell) Get(key string) (otto.Value, error) {
cell.Lock()
defer cell.Unlock()
return cell.vm.Get(key)
}
// Call attempts to call the internal call function for the giving response associated with the
// proper values.
func (cell *Cell) Call(item string, this interface{}, args ...interface{}) (otto.Value, error) {
cell.Lock()
defer cell.Unlock()
return cell.vm.Call(item, this, args...)
}
// Run evaluates the giving js string on the associated vm llop.
func (cell *Cell) Run(val string) (otto.Value, error) {
cell.Lock()
defer cell.Unlock()
return cell.vm.Run(val)
}