func main() { flag.Parse() if !*flag_underscore { underscore.Disable() } err := func() error { src, err := readSource(flag.Arg(0)) if err != nil { return err } vm := otto.New() _, err = vm.Run(src) return err }() if err != nil { switch err := err.(type) { case *otto.Error: fmt.Print(err.String()) default: fmt.Println(err) } os.Exit(64) } }
func test(filename string) error { script, err := ioutil.ReadFile(filename) if err != nil { return err } if !*flag_report { fmt.Fprintln(os.Stdout, filename, len(script)) } parse := false option := target[filename] if option != "parse" { vm := otto.New() _, err = vm.Run(string(script)) if err != nil { value := err.Error() switch { case match_ReferenceError_not_defined.MatchString(value): case match_TypeError_undefined.MatchString(value): case match_lookahead.MatchString(value): case match_backreference.MatchString(value): default: return err } parse = true } } if parse { _, err = parser.ParseFile(nil, filename, string(script), parser.IgnoreRegExpErrors) if err != nil { return err } target[filename] = "parse" } return nil }
func NewWithDocs(infoDoc []byte, tx string, data string) (self *NatSpec, err error) { var contract contractInfo err = json.Unmarshal(infoDoc, &contract) if err != nil { return } self = &NatSpec{ jsvm: otto.New(), abiDocJson: []byte(contract.AbiDefinition), userDoc: contract.UserDoc, tx: tx, data: data, } // load and require natspec js (but it is meant to be protected environment) _, err = self.jsvm.Run(natspecJS) if err != nil { return } _, err = self.jsvm.Run("var natspec = require('natspec');") return }
// Exported functions always access the vm through the event queue. You can // call the functions of the otto vm directly to circumvent the queue. These // functions should be used if and only if running a routine that was already // called from JS through an RPC call. func (self *JSRE) runEventLoop() { vm := otto.New() registry := map[*jsTimer]*jsTimer{} ready := make(chan *jsTimer) newTimer := func(call otto.FunctionCall, interval bool) (*jsTimer, otto.Value) { delay, _ := call.Argument(1).ToInteger() if 0 >= delay { delay = 1 } timer := &jsTimer{ duration: time.Duration(delay) * time.Millisecond, call: call, interval: interval, } registry[timer] = timer timer.timer = time.AfterFunc(timer.duration, func() { ready <- timer }) value, err := call.Otto.ToValue(timer) if err != nil { panic(err) } return timer, value } setTimeout := func(call otto.FunctionCall) otto.Value { _, value := newTimer(call, false) return value } setInterval := func(call otto.FunctionCall) otto.Value { _, value := newTimer(call, true) return value } clearTimeout := func(call otto.FunctionCall) otto.Value { timer, _ := call.Argument(0).Export() if timer, ok := timer.(*jsTimer); ok { timer.timer.Stop() delete(registry, timer) } return otto.UndefinedValue() } vm.Set("_setTimeout", setTimeout) vm.Set("_setInterval", setInterval) vm.Run(`var setTimeout = function(args) { if (arguments.length < 1) { throw TypeError("Failed to execute 'setTimeout': 1 argument required, but only 0 present."); } return _setTimeout.apply(this, arguments); }`) vm.Run(`var setInterval = function(args) { if (arguments.length < 1) { throw TypeError("Failed to execute 'setInterval': 1 argument required, but only 0 present."); } return _setInterval.apply(this, arguments); }`) vm.Set("clearTimeout", clearTimeout) vm.Set("clearInterval", clearTimeout) var waitForCallbacks bool loop: for { select { case timer := <-ready: // execute callback, remove/reschedule the timer var arguments []interface{} if len(timer.call.ArgumentList) > 2 { tmp := timer.call.ArgumentList[2:] arguments = make([]interface{}, 2+len(tmp)) for i, value := range tmp { arguments[i+2] = value } } else { arguments = make([]interface{}, 1) } arguments[0] = timer.call.ArgumentList[0] _, err := vm.Call(`Function.call.call`, nil, arguments...) if err != nil { fmt.Println("js error:", err, arguments) } _, inreg := registry[timer] // when clearInterval is called from within the callback don't reset it if timer.interval && inreg { timer.timer.Reset(timer.duration) } else { delete(registry, timer) if waitForCallbacks && (len(registry) == 0) { break loop } } case req := <-self.evalQueue: // run the code, send the result back req.fn(vm) close(req.done) if waitForCallbacks && (len(registry) == 0) { break loop } case waitForCallbacks = <-self.stopEventLoop: if !waitForCallbacks || (len(registry) == 0) { break loop } } } for _, timer := range registry { timer.timer.Stop() delete(registry, timer) } self.loopWg.Done() }