func (js *jsre) printBlock(call otto.FunctionCall) otto.Value { var block *types.Block if len(call.ArgumentList) > 0 { if call.Argument(0).IsNumber() { num, _ := call.Argument(0).ToInteger() block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num)) } else if call.Argument(0).IsString() { hash, _ := call.Argument(0).ToString() block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash)) } else { fmt.Println("invalid argument for dump. Either hex string or number") } } else { block = js.ethereum.ChainManager().CurrentBlock() } if block == nil { fmt.Println("block not found") return otto.UndefinedValue() } fmt.Println(block) return otto.UndefinedValue() }
// NewWriter adds a write method to the specified runtime that allows // client code to write to the specified io.Writer. // // The client function created has the following syntax: // // var response = writeMethodName(contentToWrite) // // Response object: // // { // len: bytes_written, // error: error|undefined // } func NewWriter(runtime *otto.Otto, methodName string, writer io.Writer) error { runtime.Set(methodName, func(call otto.FunctionCall) otto.Value { var data string var count int var err error var val otto.Value if data, err = call.Argument(0).ToString(); err == nil { if count, err = writer.Write([]byte(data)); err == nil { if val, err = makeMap(runtime, map[string]interface{}{"len": count}); err != nil { raiseError(runtime, "Failed to create output object: %s", err) } else { return val } } } if err != nil { if val, err := makeMap(runtime, map[string]interface{}{"len": 0, "error": err.Error()}); err != nil { raiseError(runtime, "Failed to create output object: %s", err) return otto.UndefinedValue() } else { return val } } return otto.UndefinedValue() }) return nil }
func toValue(vm *motto.Motto, value interface{}) otto.Value { var err error var val otto.Value switch n := value.(type) { case dict.Map, map[string]interface{}: bs, e := json.Marshal(n) if e != nil { err = e return otto.UndefinedValue() } object, oe := vm.Object("(" + string(bs) + ")") if oe != nil { err = oe } else { val = object.Value() } default: val, err = vm.ToValue(n) } if err != nil { log.Printf("Could not convert %v", err) return otto.UndefinedValue() } return val }
func main() { if len(os.Args) != 2 { usage() } vm := motto.New() vm.Set("fib", func(call otto.FunctionCall) otto.Value { ret := fib(40) v, _ := otto.ToValue(ret) return v }) vm.Set("XHR", func(call otto.FunctionCall) otto.Value { return otto.UndefinedValue() }) vm.Set("XHR.prototype.hello", func(call otto.FunctionCall) otto.Value { return otto.UndefinedValue() }) _, err := vm.Run(os.Args[1]) fmt.Printf("%v", err) }
func mkAssert(t *testing.T) func(otto.FunctionCall) otto.Value { return func(call otto.FunctionCall) otto.Value { name, err := call.Argument(0).ToString() if err != nil { t.Fatalf("Error getting name of assertion: %v", err) } t.Logf("RUN %v", name) got, err := call.Argument(1).Export() if err != nil { t.Errorf("Eval error on %v: %v", name, err) return otto.UndefinedValue() } exp, err := call.Argument(2).Export() if err != nil { t.Errorf("Comparison error on %v: %v", name, err) return otto.UndefinedValue() } if toInt(exp) != toInt(got) { t.Errorf("FAIL Expected %T(%v) for %v, got %T(%v)", exp, exp, name, got, got) } else { t.Logf("PASS %v", name) } return otto.UndefinedValue() } }
func apiServiceCall(call otto.FunctionCall) otto.Value { svc := call.Argument(0).String() interfaceValue, err := call.Argument(1).Export() if err != nil { logrus.Errorf("Plugins: rules: javascript supplied invalid parameters") return otto.UndefinedValue() } params := interfaceValue.(map[string]interface{}) future := service.CallService(svc, params) result := <-future.Result var res otto.Value if _, ok := result.(error); ok { res, err = otto.ToValue(result.(error).Error()) } else { res, err = otto.ToValue(result) } if err != nil { logrus.Errorf("Plugins: rules: failed to convert service result to javascript") return otto.UndefinedValue() } return res }
func NewExecutor(s stream.Stream) *Executor { e := &Executor{ incomingScripts: make(chan string), outgoingMsgs: make(chan string), incomingEvents: make(chan IncomingEvent), eventHandlers: make(map[string]map[string]otto.Value), } e.xmppStream = s e.vm = otto.New() send := func(call otto.FunctionCall) otto.Value { str, _ := call.Argument(0).ToString() e.outgoingMsgs <- str return otto.UndefinedValue() } addHandler := func(call otto.FunctionCall) otto.Value { evtName, err := call.Argument(0).ToString() handlerName, err := call.Argument(1).ToString() if err != nil { return otto.FalseValue() } val := call.Argument(2) if !val.IsFunction() { return otto.FalseValue() } handlers, ok := e.eventHandlers[evtName] if !ok { e.eventHandlers[evtName] = map[string]otto.Value{handlerName: val} } else { handlers[handlerName] = val } return otto.TrueValue() } listHandlers := func(call otto.FunctionCall) otto.Value { evtName, err := call.Argument(0).ToString() if err != nil { return otto.UndefinedValue() } list := []string{} for handlerName := range e.eventHandlers[evtName] { list = append(list, handlerName) } val, err := e.vm.ToValue(list) if err != nil { return otto.UndefinedValue() } else { return val } } chatLibrary, _ := e.vm.Object("Chat = {};") chatLibrary.Set("send", send) chatLibrary.Set("addEventHandler", addHandler) chatLibrary.Set("listEventHandlers", listHandlers) return e }
func (js *jsre) verbosity(call otto.FunctionCall) otto.Value { v, err := call.Argument(0).ToInteger() if err != nil { fmt.Println(err) return otto.UndefinedValue() } glog.SetV(int(v)) return otto.UndefinedValue() }
func (js *jsre) backtrace(call otto.FunctionCall) otto.Value { tracestr, err := call.Argument(0).ToString() if err != nil { fmt.Println(err) return otto.UndefinedValue() } glog.GetTraceLocation().Set(tracestr) return otto.UndefinedValue() }
func (self *context) CreateFile(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 2 { return otto.UndefinedValue() } path, _ := call.Argument(0).ToString() val, _ := call.Argument(1).ToString() self.ctx.CreateFile(path, []byte(val)) return otto.UndefinedValue() }
func requireFromOtto(moduleName string, vm *otto.Otto) (otto.Value, error) { rawModule, errRequire := RequireModule(moduleName) if errRequire != nil { return otto.UndefinedValue(), errRequire } module, errConvert := vm.ToValue(rawModule) if errConvert != nil { return otto.UndefinedValue(), errConvert } return module, nil }
func OttoFromGoArray(o *otto.Otto, arr []interface{}) (otto.Value, error) { ovarr, err := OttoFromGo(o, arr) if err != nil { return otto.UndefinedValue(), fmt.Errorf("could not convert arr, err: %v", err) } if ovarr.Class() != "Array" { return otto.UndefinedValue(), fmt.Errorf("expected ovarr to be array, got: %#v, class: %v, arr: %v", ovarr, ovarr.Class(), arr) } return ovarr, nil }
func (v *View) GetViewMapFunction() (*ViewMapFunction, error) { if v.preparedViewMapFunction != nil { return v.preparedViewMapFunction, nil } if v.Map == "" { return nil, fmt.Errorf("view map function missing") } o := otto.New() mapf, err := OttoNewFunction(o, v.Map) if err != nil { return nil, fmt.Errorf("view map function error: %v", err) } emits := []*ViewRow{} var emitErr error o.Set("emit", func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) <= 0 { emitErr = fmt.Errorf("emit() invoked with no parameters") return otto.UndefinedValue() } var key, value interface{} key, emitErr = call.ArgumentList[0].Export() if emitErr != nil { return otto.UndefinedValue() } if len(call.ArgumentList) >= 2 { value, emitErr = call.ArgumentList[1].Export() if emitErr != nil { return otto.UndefinedValue() } } emits = append(emits, &ViewRow{Key: key, Value: value}) return otto.UndefinedValue() }) v.preparedViewMapFunction = &ViewMapFunction{ otto: o, mapf: mapf, restartEmits: func() (resEmits []*ViewRow, resEmitErr error) { resEmits = emits resEmitErr = emitErr emits = []*ViewRow{} emitErr = nil return resEmits, resEmitErr }, } return v.preparedViewMapFunction, nil }
// RegisterMethodFileOpen registers a method that is capable of opening files. // // Response object: // // { // ok: true|false, // reader: "readFile" // the method to use to read from the file // } // // To read the entire file into a variable: // // // in Go... // RegisterMethodFileOpen(js, "openFile") // // // in the script... // var file = openFile("filename"); // open the file // var read = eval(file.reader); // get the reader method // var close = eval(file.closer); // get the closer method // // var fileContents = read(-1); // read everything // close(); // close the file // func RegisterMethodFileOpen(runtime *otto.Otto, methodName string) error { runtime.Set(methodName, func(call otto.FunctionCall) otto.Value { // check the arguments if len(call.ArgumentList) != 1 { raiseError(runtime, "%s takes 1 arguments: %s(filename)", methodName, methodName) return otto.UndefinedValue() } // get the arguments var filename string var err error if filename, err = call.Argument(0).ToString(); err != nil { raiseError(runtime, "%s first argument must be a string containing the filename", methodName) return otto.UndefinedValue() } // open the file var file io.ReadCloser if file, err = os.Open(filename); err != nil { raiseError(runtime, "Failed to open file '%s': %s", filename, err) return otto.UndefinedValue() } // add the reader var readerMethodName string = generateMethodName("fileRead") NewReader(runtime, readerMethodName, file) // add the closer var closerMethodName string = generateMethodName("fileClose") runtime.Set(closerMethodName, func(call otto.FunctionCall) otto.Value { if err := file.Close(); err != nil { raiseError(runtime, "Failed to close file '%s': %s", filename, err) return otto.FalseValue() } return otto.TrueValue() }) var response otto.Value if response, err = makeMap(runtime, map[string]interface{}{"reader": readerMethodName, "closer": closerMethodName, "ok": true}); err != nil { raiseError(runtime, "%s failed to make response map.", methodName) return otto.UndefinedValue() } // done return response }) return nil }
func (self *context) Get(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) != 1 { return otto.UndefinedValue() } key, _ := call.Argument(0).ToString() val := self.ctx.Get(key) if val != nil { return toValue(self.vm, val) } return otto.UndefinedValue() }
// myIpAddress returns the IP address of the host machine. func gopacMyIpAddress() otto.Value { hostname, err := os.Hostname() if err != nil { return otto.UndefinedValue() } address := gopacDnsResolve(hostname) if value, err := otto.ToValue(address); err == nil { return value } return otto.UndefinedValue() }
func (js *jsre) setHead(call otto.FunctionCall) otto.Value { block, err := js.getBlock(call) if err != nil { fmt.Println(err) return otto.UndefinedValue() } if block == nil { fmt.Println("block not found") return otto.UndefinedValue() } js.ethereum.ChainManager().SetHead(block) return otto.UndefinedValue() }
func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value { block, err := js.getBlock(call) if err != nil { fmt.Println(err) return otto.UndefinedValue() } if block == nil { fmt.Println("block not found") return otto.UndefinedValue() } encoded, _ := rlp.EncodeToBytes(block) return js.re.ToVal(fmt.Sprintf("%x", encoded)) }
func (js *jsre) setExtra(call otto.FunctionCall) otto.Value { extra, err := call.Argument(0).ToString() if err != nil { fmt.Println(err) return otto.UndefinedValue() } if len(extra) > 1024 { fmt.Println("error: cannot exceed 1024 bytes") return otto.UndefinedValue() } js.ethereum.Miner().SetExtra([]byte(extra)) return otto.UndefinedValue() }
// stringToValue makes an otto.Value containing the specified string. func stringToValue(message string) otto.Value { val, err := otto.ToValue(message) if err != nil { return otto.UndefinedValue() } return val }
// Invokes the JS function. Not thread-safe! This is exposed for use by unit tests. func (server *JSServer) DirectCallFunction(inputs []string) (interface{}, error) { if server.Before != nil { server.Before() } var result otto.Value var err error if server.fn.IsUndefined() { result = otto.UndefinedValue() } else { inputJS := make([]interface{}, len(inputs)) for i, inputStr := range inputs { if inputStr == "" { inputJS[i] = otto.NullValue() } else { var err error inputJS[i], err = server.js.Object("x = " + inputStr) if err != nil { return nil, fmt.Errorf("Unparseable input %q: %s", inputStr, err) } } } result, err = server.fn.Call(server.fn, inputJS...) } if server.After != nil { return server.After(result, err) } return nil, err }
func TestFetchWithHandlerParallel(t *testing.T) { m := http.NewServeMux() m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello")) }) vm := otto.New() l := loop.New(vm) if err := DefineWithHandler(vm, l, m); err != nil { panic(err) } ch := make(chan bool, 1) if err := vm.Set("__capture", func(c otto.FunctionCall) otto.Value { defer func() { ch <- true }() return otto.UndefinedValue() }); err != nil { panic(err) } must(l.EvalAndRun(`Promise.all([1,2,3,4,5].map(function(i) { return fetch('/' + i); })).then(__capture)`)) <-ch }
// Start running the JavaScript engine. func (w *JavaScript) Run() { if cmd, ok := <-w.Cmd; ok { // initial setup engine := otto.New() // define a callback for sending messages to Out engine.Set("emitOut", func(call otto.FunctionCall) otto.Value { out, err := call.Argument(0).Export() flow.Check(err) w.Out.Send(out) return otto.UndefinedValue() }) // process the command input if _, err := engine.Run(cmd.(string)); err != nil { glog.Fatal(err) } // only start the processing loop if the "onIn" handler exists value, err := engine.Get("onIn") if err == nil && value.IsFunction() { for in := range w.In { engine.Call("onIn", nil, in) } } } }
func NewChannelMapper(funcSource string) (*ChannelMapper, error) { mapper := &ChannelMapper{} mapper.js = otto.New() // Implementation of the 'sync()' callback: mapper.js.Set("sync", func(call otto.FunctionCall) otto.Value { for _, arg := range call.ArgumentList { if arg.IsString() { mapper.channels = append(mapper.channels, arg.String()) } else if arg.Class() == "Array" { array := ottoArrayToStrings(arg.Object()) if array != nil { mapper.channels = append(mapper.channels, array...) } } } return otto.UndefinedValue() }) if _, err := mapper.setFunction(funcSource); err != nil { return nil, err } mapper.requests = make(chan channelMapperRequest) go mapper.serve() return mapper, nil }
func os_remove(call otto.FunctionCall) otto.Value { if 1 <= len(call.ArgumentList) { path, _ := call.ArgumentList[0].ToString() os.RemoveAll(path) } return otto.UndefinedValue() }
func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value { txs := js.ethereum.TxPool().GetTransactions() // grab the accounts from the account manager. This will help with determening which // transactions should be returned. accounts, err := js.ethereum.AccountManager().Accounts() if err != nil { fmt.Println(err) return otto.UndefinedValue() } // Add the accouns to a new set accountSet := set.New() for _, account := range accounts { accountSet.Add(common.BytesToAddress(account.Address)) } //ltxs := make([]*tx, len(txs)) var ltxs []*tx for _, tx := range txs { // no need to check err if from, _ := tx.From(); accountSet.Has(from) { ltxs = append(ltxs, newTx(tx)) } } return js.re.ToVal(ltxs) }
func registerVM(vm *modules.JsVm) otto.Value { obj, _ := vm.Object("({})") obj.Set("do", func(c otto.FunctionCall) otto.Value { arg1 := c.Argument(0) req := JsoToRequest(arg1.Object()) followRedirObj, err := arg1.Object().Get("followRedirects") followRedirects := true if followRedirObj != otto.UndefinedValue() { followRedirects, _ = followRedirObj.ToBoolean() } client := &http.Client{} var resp *http.Response if followRedirects { resp, err = client.Do(req) } else { resp, err = http.DefaultTransport.RoundTrip(req) } respObj, _ := vm.Object("({})") if err == nil { ResponseToJso(respObj, resp) } return modules.ToResult(vm, respObj, err) }) return obj.Value() }
// Compiles a JavaScript map function to a JSMapFunction object. func NewJSMapFunction(funcSource string) (*JSMapFunction, error) { mapper := &JSMapFunction{} var err error mapper.js, err = NewJSServer(funcSource) if err != nil { return nil, err } // Implementation of the 'emit()' callback: mapper.js.DefineNativeFunction("emit", func(call otto.FunctionCall) otto.Value { key, err1 := ottoToGo(call.ArgumentList[0]) value, err2 := ottoToGo(call.ArgumentList[1]) if err1 != nil || err2 != nil { panic(fmt.Sprintf("Unsupported key or value types: key=%v, value=%v", key, value)) } mapper.output = append(mapper.output, ViewRow{Key: key, Value: value}) return otto.UndefinedValue() }) mapper.js.Before = func() { mapper.output = []ViewRow{} } mapper.js.After = func(result otto.Value, err error) (interface{}, error) { output := mapper.output mapper.output = nil return output, err } return mapper, nil }
func prettyPrintJS(call otto.FunctionCall) otto.Value { for _, v := range call.ArgumentList { prettyPrint(call.Otto, v) fmt.Println() } return otto.UndefinedValue() }
func (js *jsre) newAccount(call otto.FunctionCall) otto.Value { arg := call.Argument(0) var passphrase string if arg.IsUndefined() { fmt.Println("The new account will be encrypted with a passphrase.") fmt.Println("Please enter a passphrase now.") auth, err := readPassword("Passphrase: ", true) if err != nil { utils.Fatalf("%v", err) } confirm, err := readPassword("Repeat Passphrase: ", false) if err != nil { utils.Fatalf("%v", err) } if auth != confirm { utils.Fatalf("Passphrases did not match.") } passphrase = auth } else { var err error passphrase, err = arg.ToString() if err != nil { fmt.Println(err) return otto.FalseValue() } } acct, err := js.ethereum.AccountManager().NewAccount(passphrase) if err != nil { fmt.Printf("Could not create the account: %v", err) return otto.UndefinedValue() } return js.re.ToVal("0x" + common.Bytes2Hex(acct.Address)) }