func (v *V8Context) Eval(in string) (res interface{}, err error) { ptr := C.CString(in) defer C.free(unsafe.Pointer(ptr)) ret := C.v8_execute(v.v8context, ptr) if ret != nil { out := C.GoString(ret) if out != "" { C.free(unsafe.Pointer(ret)) if len(out) >= 14 && out[:9] == "function " && out[len(out)-1] == '}' { /* name := fmt.Sprintf("anonymous%v", &out) v.funcs[name] = func(args ...interface{}) (interface{}, error) { return (Function{v, out}).Call(args...) } return v.funcs[name], nil */ return Function{v, out}, nil } else if len(out) >= 2 && out[0] == '/' && out[len(out)-1] == '/' { res, err = regexp.Compile(jsregexp.Translate(out)) } else { var buf bytes.Buffer buf.Write([]byte(out)) dec := json.NewDecoder(&buf) err = dec.Decode(&res) } return } return nil, nil } ret = C.v8_error(v.v8context) out := C.GoString(ret) C.free(unsafe.Pointer(ret)) return nil, errors.New(out) }
//export _go_v8_callback func _go_v8_callback(contextId uint32, functionName *C.char, v8Objects *C.v8data, count C.int) *C.char { ctx := contexts[contextId] fn := ctx.funcs[C.GoString(functionName)] if fn != nil { var argv []interface{} // Parse objects i := C.int(0) for ; i < count; i++ { obj := C.v8_get_array_item(v8Objects, i) switch obj.obj_type { case C.v8regexp: argv = append(argv, regexp.MustCompile(jsregexp.Translate(C.GoString(obj.repr)))) break case C.v8function: argv = append(argv, V8Function{ctx, C.GoString(obj.repr)}) break default: // Should be a JSON string, so pass it as-is argv = append(argv, C.GoString(obj.repr)) } } // Call function ret := fn(argv...) if ret != nil { b, _ := json.Marshal(ret) return C.CString(string(b)) } return nil } return C.CString("undefined") }
//export _go_v8_callback func _go_v8_callback(contextId uint32, functionName *C.char, v8Objects *C.v8data, count C.int) *C.char { ctx := contexts[contextId] fn := ctx.funcs[C.GoString(functionName)] if fn != nil { var argv []interface{} // Parse objects i := C.int(0) for ; i < count; i++ { obj := C.v8_get_array_item(v8Objects, i) switch obj.obj_type { case C.v8regexp: argv = append(argv, regexp.MustCompile(jsregexp.Translate(C.GoString(obj.repr)))) break case C.v8function: argv = append(argv, Function{ctx, C.GoString(obj.repr)}) break case C.v8number: if f, err := strconv.ParseFloat(C.GoString(obj.repr), 64); err == nil { argv = append(argv, f) } else { argv = append(argv, 0.0) } break case C.v8string: argv = append(argv, C.GoString(obj.repr)) break case C.v8array: var a []interface{} json.Unmarshal([]byte(C.GoString(obj.repr)), &a) argv = append(argv, a) break case C.v8object: var m map[string]interface{} json.Unmarshal([]byte(C.GoString(obj.repr)), &m) argv = append(argv, m) break case C.v8boolean: if C.GoString(obj.repr) == "true" { argv = append(argv, true) } else { argv = append(argv, false) } break default: // Should be a JSON string, so pass it as-is argv = append(argv, C.GoString(obj.repr)) } } // Call function ret, err := fn(argv...) if err != nil { return nil } else if ret != nil { b, _ := json.Marshal(ret) return C.CString(string(b)) } return nil } return C.CString("undefined") }