English | 简体ä¸ć–‡
Go bindings to QuickJS: a fast, small, and embeddable ES2020 JavaScript interpreter.
- Evaluate script
- Compile script into bytecode and Eval from bytecode
- Operate JavaScript values and objects in Go
- Bind Go function to JavaScript async/sync function
- Simple exception throwing and catching
- Free
quickjs.Runtimeandquickjs.Contextonce you are done using them. - Free
quickjs.Value's returned byEval()andEvalFile(). All other values do not need to be freed, as they get garbage-collected. - Use
ExecuteAllPendingJobswait for promise/job result after you using promise/job - You may access the stacktrace of an error returned by
Eval()orEvalFile()by casting it to a*quickjs.Error. - Make new copies of arguments should you want to return them in functions you created.
import "github.com/buke/quickjs-go"package main import ( "fmt" "github.com/buke/quickjs-go" ) func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // Create a new context ctx := rt.NewContext() defer ctx.Close() ret, err := ctx.Eval("'Hello ' + 'QuickJS!'") if err != nil { println(err.Error()) } fmt.Println(ret.String()) }package main import ( "fmt" "github.com/buke/quickjs-go" ) func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // Create a new context ctx := rt.NewContext() defer ctx.Close() test := ctx.Object() test.Set("A", ctx.String("String A")) test.Set("B", ctx.String("String B")) test.Set("C", ctx.String("String C")) ctx.Globals().Set("test", test) ret, _ := ctx.Eval(`Object.keys(test).map(key => test[key]).join(" ")`) defer ret.Free() fmt.Println(ret.String()) }package main import "github.com/buke/quickjs-go" func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // Create a new context ctx := rt.NewContext() defer ctx.Close() // Create a new object test := ctx.Object() defer test.Free() // bind properties to the object test.Set("A", test.Context().String("String A")) test.Set("B", ctx.Int32(0)) test.Set("C", ctx.Bool(false)) // bind go function to js object test.Set("hello", ctx.Function(func(ctx *quickjs.Context, this quickjs.Value, args []quickjs.Value) quickjs.Value { return ctx.String("Hello " + args[0].String()) })) // bind "test" object to global object ctx.Globals().Set("test", test) // call js function by js js_ret, _ := ctx.Eval(`test.hello("Javascript!")`) fmt.Println(js_ret.String()) // call js function by go go_ret := ctx.Globals().Get("test").Call("hello", ctx.String("Golang!")) fmt.Println(go_ret.String()) //bind go function to Javascript async function ctx.Globals().Set("testAsync", ctx.AsyncFunction(func(ctx *quickjs.Context, this quickjs.Value, promise quickjs.Value, args []quickjs.Value) { promise.Call("resolve", ctx.String("Hello Async Function!")) })) ret, _ := ctx.Eval(` var ret; testAsync().then(v => ret = v) `) defer ret.Free() // wait for promise resolve rt.ExecuteAllPendingJobs() //get promise result asyncRet, _ := ctx.Eval("ret") defer asyncRet.Free() fmt.Println(asyncRet.String()) // Output: // Hello Javascript! // Hello Golang! // Hello Async Function! }package main import ( "fmt" "github.com/buke/quickjs-go" ) func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // Create a new context ctx := rt.NewContext() defer ctx.Close() ctx.Globals().SetFunction("A", func(ctx *Context, this Value, args []Value) Value { // raise error return ctx.ThrowError(expected) }) _, actual := ctx.Eval("A()") fmt.Println(actual.Error()) }package main import ( "fmt" "github.com/buke/quickjs-go" ) func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // Create a new context ctx := rt.NewContext() defer ctx.Close() jsStr := ` function fib(n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fib(n - 1) + fib(n - 2); } fib(10) ` // Compile the script to bytecode buf, _ := ctx.Compile(jsStr) // Create a new runtime rt2 := quickjs.NewRuntime() defer rt2.Close() // Create a new context ctx2 := rt2.NewContext() defer ctx2.Close() //Eval bytecode result, _ := ctx2.EvalBytecode(buf) fmt.Println(result.Int32()) }package main import ( "fmt" "github.com/buke/quickjs-go" ) func main() { // Create a new runtime rt := quickjs.NewRuntime() defer rt.Close() // set runtime options rt.SetMemoryLimit(256 * 1024) //256KB rt.SetMaxStackSize(65534) // Create a new context ctx := rt.NewContext() defer ctx.Close() result, err := ctx.Eval(`var array = []; while (true) { array.push(null) }`) defer result.Free() }Go Reference & more examples: https://pkg.go.dev/github.com/buke/quickjs-go