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) }
// 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 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 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 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 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 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 createContext(vm *otto.Otto, event chan otto.Value) otto.Value { var cbfunc = func(invar ...interface{}) { var lovar otto.Value if len(invar) > 0 { lovar, _ = vm.ToValue(invar[0]) } else { lovar = otto.NullValue() } event <- lovar close(event) } vm.Set("_iopipe_cb", cbfunc) vm.Run(`_iopipe_context = { "done": _iopipe_cb, "success": _iopipe_cb, "fail": _iopipe_cb }`) jscontext, _ := vm.Get("_iopipe_context") return jscontext }
func reverseGremlinChainHelper(env *otto.Otto, chain *otto.Object, newBase *otto.Object, tag string) (*otto.Object, *otto.Object) { kindVal, _ := chain.Get("_gremlin_type") kind, _ := kindVal.ToString() if tag != "" { if kind == "tag" { tags := getStringArgs(chain) for _, t := range tags { if t == tag { return newBase, chain } } } } if kind == "morphism" || kind == "vertex" { return newBase, chain } var newKind string switch kind { case "in": newKind = "out" case "out": newKind = "in" default: newKind = kind } prev, _ := chain.Get("_gremlin_prev") env.Run("var out = {}") out, _ := env.Object("out") out.Set("_gremlin_type", newKind) values, _ := chain.Get("_gremlin_values") out.Set("_gremlin_values", values) back, _ := chain.Get("_gremlin_back_chain") out.Set("_gremlin_back_chain", back) out.Set("_gremlin_prev", newBase) strings, _ := chain.Get("string_args") out.Set("string_args", strings) return reverseGremlinChainHelper(env, prev.Object(), out, tag) }
func Define(vm *otto.Otto, l *loop.Loop) error { if v, err := vm.Get("Promise"); err != nil { return err } else if !v.IsUndefined() { return nil } if err := timers.Define(vm, l); err != nil { return err } s, err := vm.Compile("bundle.js", rice.MustFindBox("dist-promise").MustString("bundle.js")) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } return nil }
func Define(vm *otto.Otto, l *loop.Loop) error { if v, err := vm.Get("Promise"); err != nil { return err } else if !v.IsUndefined() { return nil } if err := timers.Define(vm, l); err != nil { return err } s, err := vm.Compile("promise-bundle.js", src) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } return nil }
func runUnsafeJavascript(vm *otto.Otto, unsafe string) (otto.Value, error) { start := time.Now() defer func() { duration := time.Since(start) if err := recover(); err != nil { if err == halt { fmt.Println("Some code took too long! Stopping after: ", duration) } panic(err) } }() vm.Interrupt = make(chan func(), 1) go func() { time.Sleep(maxExecutionTime * time.Second) vm.Interrupt <- func() { panic(halt) } }() return vm.Run(unsafe) }
func makeFilterWithVM(vm *otto.Otto, script string) (func(input string) (string, error), error) { var ( res *http.Response body []byte err error ) res, err = http.Get(REQUIREJS_URL) if err != nil { log.Fatal(err) } body, err = ioutil.ReadAll(res.Body) if err != nil { log.Fatal(err) } res.Body.Close() rjs := string(body[:]) return func(input string) (string, error) { logrus.Debug("Adding RequireJS") vm.Run(rjs) logrus.Debug("Executing script: " + script) _, err := vm.Run(` var module = { "exports": function() { } } `) if err != nil { return "", err } _, err = vm.Run(script) if err != nil { return "", err } event := make(chan otto.Value) oval, err := vm.ToValue(input) if err != nil { return "", err } jscontext := createContext(vm, event) go vm.Call("module.exports", nil, oval, jscontext) value := <-event return value.ToString() }, nil }
func setupGremlin(env *otto.Otto, ses *Session) { graph, _ := env.Object("graph = {}") graph.Set("Vertex", func(call otto.FunctionCall) otto.Value { call.Otto.Run("var out = {}") out, err := call.Otto.Object("out") if err != nil { glog.Error(err.Error()) return otto.TrueValue() } out.Set("_gremlin_type", "vertex") outStrings := concatStringArgs(call) if len(*outStrings) > 0 { out.Set("string_args", *outStrings) } embedTraversals(env, ses, out) embedFinals(env, ses, out) return out.Value() }) graph.Set("Morphism", func(call otto.FunctionCall) otto.Value { call.Otto.Run("var out = {}") out, _ := call.Otto.Object("out") out.Set("_gremlin_type", "morphism") embedTraversals(env, ses, out) return out.Value() }) graph.Set("Emit", func(call otto.FunctionCall) otto.Value { value := call.Argument(0) if value.IsDefined() { ses.SendResult(&GremlinResult{metaresult: false, err: "", val: &value, actualResults: nil}) } return otto.NullValue() }) env.Run("graph.V = graph.Vertex") env.Run("graph.M = graph.Morphism") env.Run("g = graph") }
func injectRuntime(vm *otto.Otto) { var err error err = vm.Set("sqrt", func(call otto.FunctionCall) otto.Value { f, err := call.Argument(0).ToFloat() if err != nil { panic(err) } r, err := otto.ToValue(math.Sqrt(f)) if err != nil { panic(err) } return r }) _, err = vm.Run(` gnr = { lerp: function(minIn, maxIn, minOut, maxOut) { return function(d) { return (d - minIn)/(maxIn - minIn)*(maxOut - minOut) + minOut; } }, lerpCap: function(minIn, maxIn, minOut, maxOut) { var f = gnr.lerp(minIn, maxIn, minOut, maxOut); return function(d) { if(d < minIn) { d = minIn; } if(d > maxIn) { d = maxIn; } return f(d); } }, vlerp: function(minIn, maxIn, minOut, maxOut) { var xLerp = gnr.lerp(minIn, maxIn, minOut.X, maxOut.X); var yLerp = gnr.lerp(minIn, maxIn, minOut.Y, maxOut.Y); var zLerp = gnr.lerp(minIn, maxIn, minOut.Z, maxOut.Z); return function(d) { return { X: xLerp(d), Y: yLerp(d), Z: zLerp(d) }; }; }, vlerpCap: function(minIn, maxIn, minOut, maxOut) { var xLerp = gnr.lerpCap(minIn, maxIn, minOut.X, maxOut.X); var yLerp = gnr.lerpCap(minIn, maxIn, minOut.Y, maxOut.Y); var zLerp = gnr.lerpCap(minIn, maxIn, minOut.Z, maxOut.Z); return function(d) { return { X: xLerp(d), Y: yLerp(d), Z: zLerp(d) }; }; }, vector2Color: function(v) { return { r: v.X, g: v.Y, b: v.Z }; }, vector: { product: function(v1, v2) { return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z; }, length: function(v) { return sqrt(gnr.vector.product(v, v)); } } } `) if err != nil { panic(err) } }
func handleJavascript(w http.ResponseWriter, r *http.Request) { r.ParseForm() js := r.FormValue("js") if js == "" { js = "{};" } pretty := r.FormValue("pretty") switch pretty { case "": pretty = "true" case "true": default: pretty = "false" } log.Printf("javascript: executing %s\n", js) var vm *otto.Otto if *sharedHttpVM { if httpVM == nil { httpVM = otto.New() InitEnv(httpVM) } vm = httpVM } else { vm = otto.New() InitEnv(vm) } o, err := vm.Run(js) if err != nil { log.Printf("javascript: warning: user error: %v", err) fmt.Fprintf(w, `{"error":"%v", "js":"%s"}`, err, js) return } x, err := o.Export() // fmt.Fprintf(os.Stderr, "got %v (%v)\n", x, err) if err != nil { log.Printf("javascript: warning: export error: %v", err) fmt.Fprintf(w, `{"error":"%v", "js":"%s"}`, err, js) return } var bs []byte if pretty == "true" { bs, err = json.MarshalIndent(&x, " ", " ") } else { bs, err = json.Marshal(&x) } if err != nil { log.Printf("javascript: warning: marshal error: %v", err) fmt.Fprintf(w, `{"error":"%v", "js":"%s"}`, err, js) return } log.Printf("javascript: returning %d bytes\n", len(bs)) fmt.Fprintf(w, "%s\n", bs) }
func DefineWithHandler(vm *otto.Otto, l *loop.Loop, h http.Handler) error { if err := promise.Define(vm, l); err != nil { return err } jsData := rice.MustFindBox("dist-fetch").MustString("bundle.js") smData := rice.MustFindBox("dist-fetch").MustString("bundle.js.map") s, err := vm.CompileWithSourceMap("fetch-bundle.js", jsData, smData) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } vm.Set("__private__fetch_execute", func(c otto.FunctionCall) otto.Value { jsReq := c.Argument(0).Object() jsRes := c.Argument(1).Object() cb := c.Argument(2) method := mustValue(jsReq.Get("method")).String() urlStr := mustValue(jsReq.Get("url")).String() jsBody := mustValue(jsReq.Get("body")) var body io.Reader if jsBody.IsString() { body = strings.NewReader(jsBody.String()) } t := &fetchTask{ jsReq: jsReq, jsRes: jsRes, cb: cb, } l.Add(t) go func() { defer l.Ready(t) req, err := http.NewRequest(method, urlStr, body) if err != nil { t.err = err return } if h != nil && urlStr[0] == '/' { res := httptest.NewRecorder() h.ServeHTTP(res, req) t.status = res.Code t.statusText = http.StatusText(res.Code) t.headers = res.Header() t.body = res.Body.Bytes() } else { res, err := http.DefaultClient.Do(req) if err != nil { t.err = err return } d, err := ioutil.ReadAll(res.Body) if err != nil { t.err = err return } t.status = res.StatusCode t.statusText = res.Status t.headers = res.Header t.body = d } }() return otto.UndefinedValue() }) return nil }
func DefineWithHandler(vm *otto.Otto, l *loop.Loop, h http.Handler) error { if err := promise.Define(vm, l); err != nil { return err } s, err := vm.Compile("fetch.js", rice.MustFindBox("dist-fetch").MustString("bundle.js")) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } vm.Set("__private__fetch_execute", func(c otto.FunctionCall) otto.Value { jsReq := c.Argument(0).Object() jsRes := c.Argument(1).Object() cb := c.Argument(2) method := mustValue(jsReq.Get("method")).String() urlStr := mustValue(jsReq.Get("url")).String() jsBody := mustValue(jsReq.Get("body")) var body io.Reader if jsBody.IsString() { body = strings.NewReader(jsBody.String()) } t := &fetchTask{ jsReq: jsReq, jsRes: jsRes, cb: cb, } l.Add(t) go func() { defer l.Ready(t) req, err := http.NewRequest(method, urlStr, body) if err != nil { t.err = err return } if h != nil && urlStr[0] == '/' { res := httptest.NewRecorder() h.ServeHTTP(res, req) jsRes.Set("status", res.Code) jsRes.Set("statusText", http.StatusText(res.Code)) h := mustValue(jsRes.Get("headers")).Object() for k, vs := range res.Header() { for _, v := range vs { if _, err := h.Call("append", k, v); err != nil { t.err = err return } } } jsRes.Set("_body", string(res.Body.Bytes())) } else { res, err := http.DefaultClient.Do(req) if err != nil { t.err = err return } jsRes.Set("status", res.StatusCode) jsRes.Set("statusText", res.Status) h := mustValue(jsRes.Get("headers")).Object() for k, vs := range res.Header { for _, v := range vs { if _, err := h.Call("append", k, v); err != nil { t.err = err return } } } d, err := ioutil.ReadAll(res.Body) if err != nil { t.err = err return } jsRes.Set("_body", string(d)) } }() return otto.UndefinedValue() }) return nil }
// makeMap makes a map inside the specified runtime, and returns the // otto.Value containing the object, or an error if something went wrong. func makeMap(runtime *otto.Otto, m map[string]interface{}) (otto.Value, error) { return runtime.Run(fmt.Sprintf("eval(%s);", toJson(m))) }