package jsre import ( "fmt" "io/ioutil" "github.com/robertkrimen/otto" "github.com/ethereum/go-ethereum/common" ) /* JSRE is a generic JS runtime environment embedding the otto JS interpreter. It provides some helper functions to - load code from files - run code snippets - require libraries - bind native go objects */ type JSRE struct { assetPath string vm *otto.Otto } func New(assetPath string) *JSRE { re := &JSRE{ assetPath, otto.New(), } // load prettyprint func definition re.vm.Run(pp_js) re.vm.Set("loadScript", re.loadScript) return re } // Exec(file) loads and runs the contents of a file // if a relative path is given, the jsre's assetPath is used func (self *JSRE) Exec(file string) error { return self.exec(common.AbsolutePath(self.assetPath, file)) } func (self *JSRE) exec(path string) error { code, err := ioutil.ReadFile(path) if err != nil { return err } _, err = self.vm.Run(code) return err } func (self *JSRE) Bind(name string, v interface{}) (err error) { self.vm.Set(name, v) return } func (self *JSRE) Run(code string) (otto.Value, error) { return self.vm.Run(code) } func (self *JSRE) Get(ns string) (otto.Value, error) { return self.vm.Get(ns) } func (self *JSRE) Set(ns string, v interface{}) error { return self.vm.Set(ns, v) } func (self *JSRE) loadScript(call otto.FunctionCall) otto.Value { file, err := call.Argument(0).ToString() if err != nil { return otto.FalseValue() } if err := self.Exec(file); err != nil { fmt.Println("err:", err) return otto.FalseValue() } return otto.TrueValue() } func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) { var method otto.Value v, err = self.vm.ToValue(v) if err != nil { return } method, err = self.vm.Get("prettyPrint") if err != nil { return } return method.Call(method, v) } func (self *JSRE) ToVal(v interface{}) otto.Value { result, err := self.vm.ToValue(v) if err != nil { fmt.Println("Value unknown:", err) return otto.UndefinedValue() } return result } func (self *JSRE) Eval(code string) (s string, err error) { var val otto.Value val, err = self.Run(code) if err != nil { return } val, err = self.PrettyPrint(val) if err != nil { return } return fmt.Sprintf("%v", val), nil } func (self *JSRE) Compile(fn string, src interface{}) error { script, err := self.vm.Compile(fn, src) if err != nil { return err } self.vm.Run(script) return nil }