func (t *timerTask) Execute(vm *otto.Otto, l *loop.Loop) error { var arguments []interface{} if len(t.call.ArgumentList) > 2 { tmp := t.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] = t.call.ArgumentList[0] if _, err := vm.Call(`Function.call.call`, nil, arguments...); err != nil { return err } if t.interval && !t.stopped { t.timer.Reset(t.duration) l.Add(t) } return nil }
func testUndefined(vm *otto.Otto, src string) error { v, err := vm.Run(src) if err == nil && !v.IsUndefined() { err = fmt.Errorf("expected undefined, got %v", v) } return err }
func compileAndRun(vm *otto.Otto, filename string, src interface{}) (otto.Value, error) { script, err := vm.Compile(filename, src) if err != nil { return otto.Value{}, err } return vm.Run(script) }
// 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 (t *fetchTask) Execute(vm *otto.Otto, l *loop.Loop) error { var arguments []interface{} if t.err != nil { e, err := vm.Call(`new Error`, nil, t.err.Error()) if err != nil { return err } arguments = append(arguments, e) } t.jsRes.Set("status", t.status) t.jsRes.Set("statusText", t.statusText) h := mustValue(t.jsRes.Get("headers")).Object() for k, vs := range t.headers { for _, v := range vs { if _, err := h.Call("append", k, v); err != nil { return err } } } t.jsRes.Set("_body", string(t.body)) if _, err := t.cb.Call(otto.NullValue(), arguments...); err != nil { return err } return nil }
// Bind binds the method to the specified runtime. func (m *Method) Bind(runtime *otto.Otto) error { castFunc := (func(call otto.FunctionCall) otto.Value)(m.Func) if err := runtime.Set("$$"+m.Name, castFunc); err != nil { return err } return nil }
func getCompletions(vm *otto.Otto, line string) (results []string) { parts := strings.Split(line, ".") objRef := "this" prefix := line if len(parts) > 1 { objRef = strings.Join(parts[0:len(parts)-1], ".") prefix = parts[len(parts)-1] } obj, _ := vm.Object(objRef) if obj == nil { return nil } iterOwnAndConstructorKeys(vm, obj, func(k string) { if strings.HasPrefix(k, prefix) { if objRef == "this" { results = append(results, k) } else { results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k) } } }) // e.g. web3<tab><tab> append dot since its an object if obj, _ = vm.Object(line); obj != nil { results = append(results, line+".") } sort.Strings(results) return results }
func (ctrl *JsController) addDiscoveryService(o *otto.Otto) { o.Set("discover", func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) == 0 { glog.Errorf("DISCOVER: Missing arguments") return otto.NullValue() } url, _ := call.Argument(0).ToString() upstreams, err := ctrl.DiscoveryService.Get(url) if err != nil { glog.Errorf("Failed to discover upstreams: %v", err) return otto.NullValue() } glog.Infof("Discovered upstreams: %v", upstreams) result, err := o.ToValue(upstreams) if err != nil { glog.Errorf("Failed to convert: %v", err) return otto.NullValue() } return result }) }
// Exist gets whether a variable exists in the runtime or not. func Exist(runtime *otto.Otto, name string) bool { if val, err := runtime.Get(name); err == nil { return val != otto.UndefinedValue() } return false }
func (b Buffers) Sync(o *otto.Otto) error { if v, err := o.ToValue(b); err != nil { return err } else { o.Set("buffers", v) } return nil }
// now we be sure to cleanup the environment as best we can func cleanupDocumentFromEnvironment(o *otto.Otto, doc Document) { for k, _ := range doc { _, err := o.Run(k + "=undefined") if err != nil { log.Printf("Error running otto cleanup: %v", err) } } }
func evaluateExpressionInEnvironment(o *otto.Otto, expr parser.Expression) otto.Value { result, err := o.Run(fmt.Sprintf("ignore = %v", expr)) if err != nil { log.Printf("Error running otto eval %v, %v", expr, err) } else { return result } return otto.UndefinedValue() }
func run(vm *otto.Otto, filename string, code string) (otto.Value, error) { // Compile before running so that stacktraces have filenames. script, err := vm.Compile(filename, code) if err != nil { return otto.Value{}, err } return vm.Run(script) }
func (ctrl *JsController) addLoggers(o *otto.Otto) { o.Set("info", func(call otto.FunctionCall) otto.Value { return log("info", call) }) o.Set("error", func(call otto.FunctionCall) otto.Value { return log("error", call) }) }
func newError(o *otto.Otto, inError error) otto.Value { obj := errorToJs(inError) jsObj, err := o.ToValue(obj) if err != nil { glog.Errorf("Error: %s", err) return otto.NullValue() } return jsObj }
func testString(vm *otto.Otto, src string) (string, error) { v, err := vm.Run(src) if err == nil { if !v.IsString() { err = fmt.Errorf("expected String, got %v", v) } else { return v.ToString() } } return "", err }
// Execute runs the EvalTask's otto.Script in the vm provided, pushing the // resultant return value and error (or nil) into the associated channels. // If the execution results in an error, it will return that error. func (e EvalTask) Execute(vm *otto.Otto, l *loop.Loop) error { v, err := vm.Run(e.Script) e.Value <- v e.Error <- err if e.SoftError { return nil } return err }
func testBoolean(vm *otto.Otto, src string) (bool, error) { v, err := vm.Run(src) if err == nil { if !v.IsBoolean() { err = fmt.Errorf("expected Boolean, got %v", v) } else { return v.ToBoolean() } } return false, err }
func getConstant(vm *otto.Otto, name string) string { val, err := vm.Get(name) if err != nil { return "" } str, err := val.ToString() if err != nil { return "" } return str }
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 }
// 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 reverseGremlinChainTo(env *otto.Otto, prevObj *otto.Object, tag string) (*otto.Object, *otto.Object) { env.Run("var _base_object = {}") base, err := env.Object("_base_object") if err != nil { glog.Error(err) return otto.NullValue().Object(), otto.NullValue().Object() } if isVertexChain(prevObj) { base.Set("_gremlin_type", "vertex") } else { base.Set("_gremlin_type", "morphism") } return reverseGremlinChainHelper(env, prevObj, base, tag) }
func evaluateExpressionInEnvironmentAsInteger(o *otto.Otto, expr parser.Expression) int64 { result, err := o.Run(fmt.Sprintf("%v", expr)) if err != nil { log.Printf("Error running otto %v", err) } else { result, err := result.ToInteger() if err != nil { log.Printf("Error converting otto result to integer %v", err) } else { return result } } return -1 }
// serialize all the top level elements of doc to JSON and // put them in the environment // FIXME there has to be a better way than this func putDocumentIntoEnvironment(o *otto.Otto, doc Document) { for k, v := range doc { v_json, err := json.Marshal(v) if err != nil { log.Printf("JSON serialization failed: %v", err) } else { _, err := o.Run(k + "=" + string(v_json)) if err != nil { log.Printf("Error running otto put: %v", err) } } } }
func evaluateExpressionStringInEnvironmentAsBoolean(o *otto.Otto, expression string) bool { result, err := o.Run(expression) if err != nil { log.Printf("Error running otto %v, %v", expression, err) } else { //log.Printf("result was %v", result) result, err := result.ToBoolean() if err != nil { log.Printf("Error converting otto result to boolean %v", err) } else if result { return true } } return false }
func SetOttoVM(vm *otto.Otto, pmap map[string]string, key string, ptype string) { if value, ok := pmap[key]; ok { switch ptype { case "string": vm.Set(key, value) case "int": intval, err := strconv.Atoi(value) if err != nil { log.Println(err.Error()) } else { vm.Set(key, intval) } } } }
func funcToOtto(context *otto.Otto, fn reflect.Value) interface{} { return func(call otto.FunctionCall) otto.Value { convertedArgs := make([]reflect.Value, 0) for _, v := range call.ArgumentList { exported, _ := v.Export() convertedArgs = append(convertedArgs, reflect.ValueOf(exported)) } ret := fn.Call(convertedArgs) if len(ret) > 0 { val, _ := context.ToValue(ret[0].Interface()) return val } else { return otto.UndefinedValue() } } }
// SetOnce sets a name or value only if it doesn't exist. // // Returns whether the value was set or not, or an error if it failed to // set it. // // For acceptable values, see http://godoc.org/github.com/robertkrimen/otto#Otto.Set func SetOnce(runtime *otto.Otto, name string, value interface{}) (bool, error) { if !Exist(runtime, name) { if err := runtime.Set(name, value); err != nil { return false, err } return true, nil } // nothing to do return false, nil }
func parseContext(vm *otto.Otto) (stc Stitch, err error) { vmCtx, err := vm.Run("deployment.toQuiltRepresentation()") if err != nil { return stc, err } // Export() always returns `nil` as the error (it's only present for // backwards compatibility), so we can safely ignore it. exp, _ := vmCtx.Export() ctxStr, err := json.Marshal(exp) if err != nil { return stc, err } err = json.Unmarshal(ctxStr, &stc) return stc, err }
func iterOwnKeys(vm *otto.Otto, obj *otto.Object, f func(string)) { Object, _ := vm.Object("Object") rv, _ := Object.Call("getOwnPropertyNames", obj.Value()) gv, _ := rv.Export() switch gv := gv.(type) { case []interface{}: for _, v := range gv { f(v.(string)) } case []string: for _, v := range gv { f(v) } default: panic(fmt.Errorf("Object.getOwnPropertyNames returned unexpected type %T", gv)) } }