1 Star 1 Fork 0

buke / quickjs-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

quickjs-go

English | 简体中文

Test codecov Go Report Card GoDoc FOSSA Status

Go 语言的QuickJS绑定库:快速、小型、可嵌入的ES2020 JavaScript解释器。

版本支持

quickjs-go QuickJS
v0.1.x v2021-03-27
v0.2.x v2023-12-09
v0.3.x v2024-01-13
v0.4.x v2024-02-14

功能

  • 执行javascript脚本
  • 编译javascript脚本到字节码并执行字节码
  • 在 Go 中操作 JavaScript 值和对象
  • 绑定 Go 函数到 JavaScript 同步函数和异步函数
  • 简单的异常抛出和捕获

指南

  1. 在使用完毕后,请记得关闭 quickjs.Runtimequickjs.Context
  2. 请记得关闭由 Eval()EvalFile() 返回的 quickjs.Value。其他值不需要关闭,因为它们会被垃圾回收。
  3. 如果你使用了promise 或 async function,请使用 ctx.Loop() 等待所有的promise/job结果。
  4. You may access the stacktrace of an error returned by Eval() or EvalFile() by casting it to a *quickjs.Error.
  5. 如果Eval()EvalFile()返回了错误,可强制转换为*quickjs.Error以读取错误的堆栈信息。
  6. 如果你想在函数中返回参数,请在函数中复制参数。

用法

import "github.com/buke/quickjs-go"

执行javascript脚本

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())
}

读取/设置 JavaScript 对象

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
	ctx.Loop()

    //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())
}

Bytecode编译和执行


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())
}

设置内存、栈、GC等等

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 语言文档和示例: https://pkg.go.dev/github.com/buke/quickjs-go

协议

MIT

FOSSA Status

相关项目

MIT License Copyright (c) 2022 Brian Wang <wangbuke@gmail.com> Copyright (c) 2020 Kenta Iwasaki <kenta@lithdew.net> Copyright (c) 2017-2020 Fabrice Bellard Copyright (c) 2017-2020 Charlie Gordon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

Go bindings to QuickJS 展开 收起
Go 等 2 种语言
MIT
取消

发行版 (4)

全部

贡献者

全部

近期动态

加载更多
不能加载更多了
Go
1
https://gitee.com/wangbuke/quickjs-go.git
git@gitee.com:wangbuke/quickjs-go.git
wangbuke
quickjs-go
quickjs-go
main

搜索帮助

53164aa7 5694891 3bd8fe86 5694891