diff options
Diffstat (limited to 'javascript/javascript_runtime.go')
-rw-r--r-- | javascript/javascript_runtime.go | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/javascript/javascript_runtime.go b/javascript/javascript_runtime.go new file mode 100644 index 000000000..0a137f72a --- /dev/null +++ b/javascript/javascript_runtime.go @@ -0,0 +1,103 @@ +package javascript + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" + "github.com/obscuren/otto" +) + +var jsrelogger = logger.NewLogger("JSRE") + +type JSRE struct { + Vm *otto.Otto + xeth *xeth.XEth + + objectCb map[string][]otto.Value +} + +func (jsre *JSRE) LoadExtFile(path string) { + result, err := ioutil.ReadFile(path) + if err == nil { + jsre.Vm.Run(result) + } else { + jsrelogger.Infoln("Could not load file:", path) + } +} + +func (jsre *JSRE) LoadIntFile(file string) { + assetPath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext") + jsre.LoadExtFile(path.Join(assetPath, file)) +} + +func NewJSRE(xeth *xeth.XEth) *JSRE { + re := &JSRE{ + otto.New(), + xeth, + make(map[string][]otto.Value), + } + + // Init the JS lib + re.Vm.Run(jsLib) + + // Load extra javascript files + re.LoadIntFile("bignumber.min.js") + + re.Bind("eth", &JSEthereum{re.xeth, re.Vm}) + + re.initStdFuncs() + + jsrelogger.Infoln("started") + + return re +} + +func (self *JSRE) Bind(name string, v interface{}) { + self.Vm.Set(name, v) +} + +func (self *JSRE) Run(code string) (otto.Value, error) { + return self.Vm.Run(code) +} + +func (self *JSRE) initStdFuncs() { + t, _ := self.Vm.Get("eth") + eth := t.Object() + eth.Set("require", self.require) +} + +func (self *JSRE) Require(file string) error { + if len(filepath.Ext(file)) == 0 { + file += ".js" + } + + fh, err := os.Open(file) + if err != nil { + return err + } + + content, _ := ioutil.ReadAll(fh) + self.Run("exports = {};(function() {" + string(content) + "})();") + + return nil +} + +func (self *JSRE) require(call otto.FunctionCall) otto.Value { + file, err := call.Argument(0).ToString() + if err != nil { + return otto.UndefinedValue() + } + if err := self.Require(file); err != nil { + fmt.Println("err:", err) + return otto.UndefinedValue() + } + + t, _ := self.Vm.Get("exports") + + return t +} |