jsre.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package jsre
  2. import (
  3. "fmt"
  4. "github.com/obscuren/otto"
  5. "io/ioutil"
  6. "github.com/ethereum/go-ethereum/common"
  7. )
  8. /*
  9. JSRE is a generic JS runtime environment embedding the otto JS interpreter.
  10. It provides some helper functions to
  11. - load code from files
  12. - run code snippets
  13. - require libraries
  14. - bind native go objects
  15. */
  16. type JSRE struct {
  17. assetPath string
  18. vm *otto.Otto
  19. }
  20. func New(assetPath string) *JSRE {
  21. re := &JSRE{
  22. assetPath,
  23. otto.New(),
  24. }
  25. // load prettyprint func definition
  26. re.vm.Run(pp_js)
  27. re.vm.Set("loadScript", re.loadScript)
  28. return re
  29. }
  30. // Exec(file) loads and runs the contents of a file
  31. // if a relative path is given, the jsre's assetPath is used
  32. func (self *JSRE) Exec(file string) error {
  33. return self.exec(common.AbsolutePath(self.assetPath, file))
  34. }
  35. func (self *JSRE) exec(path string) error {
  36. code, err := ioutil.ReadFile(path)
  37. if err != nil {
  38. return err
  39. }
  40. _, err = self.vm.Run(code)
  41. return err
  42. }
  43. func (self *JSRE) Bind(name string, v interface{}) (err error) {
  44. self.vm.Set(name, v)
  45. return
  46. }
  47. func (self *JSRE) Run(code string) (otto.Value, error) {
  48. return self.vm.Run(code)
  49. }
  50. func (self *JSRE) Get(ns string) (otto.Value, error) {
  51. return self.vm.Get(ns)
  52. }
  53. func (self *JSRE) Set(ns string, v interface{}) error {
  54. return self.vm.Set(ns, v)
  55. }
  56. func (self *JSRE) loadScript(call otto.FunctionCall) otto.Value {
  57. file, err := call.Argument(0).ToString()
  58. if err != nil {
  59. return otto.FalseValue()
  60. }
  61. if err := self.Exec(file); err != nil {
  62. fmt.Println("err:", err)
  63. return otto.FalseValue()
  64. }
  65. return otto.TrueValue()
  66. }
  67. func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) {
  68. var method otto.Value
  69. v, err = self.vm.ToValue(v)
  70. if err != nil {
  71. return
  72. }
  73. method, err = self.vm.Get("prettyPrint")
  74. if err != nil {
  75. return
  76. }
  77. return method.Call(method, v)
  78. }
  79. func (self *JSRE) ToVal(v interface{}) otto.Value {
  80. result, err := self.vm.ToValue(v)
  81. if err != nil {
  82. fmt.Println("Value unknown:", err)
  83. return otto.UndefinedValue()
  84. }
  85. return result
  86. }
  87. func (self *JSRE) Eval(code string) (s string, err error) {
  88. var val otto.Value
  89. val, err = self.Run(code)
  90. if err != nil {
  91. return
  92. }
  93. val, err = self.PrettyPrint(val)
  94. if err != nil {
  95. return
  96. }
  97. return fmt.Sprintf("%v", val), nil
  98. }