aboutsummaryrefslogtreecommitdiffstats
path: root/jsre/jsre.go
diff options
context:
space:
mode:
Diffstat (limited to 'jsre/jsre.go')
-rw-r--r--jsre/jsre.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/jsre/jsre.go b/jsre/jsre.go
new file mode 100644
index 000000000..31ea955e6
--- /dev/null
+++ b/jsre/jsre.go
@@ -0,0 +1,115 @@
+package jsre
+
+import (
+ "fmt"
+ "github.com/obscuren/otto"
+ "io/ioutil"
+
+ "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
+}