quickjs-go icon indicating copy to clipboard operation
quickjs-go copied to clipboard

您好,在使用中遇到两个问题,关于gc和生成字节码的

Open wildfire810 opened this issue 1 year ago • 1 comments

我在生成字节码时,需要根据脚本载入所有模块,所以是否可以暴露载入模块的回调? 另外,我想要调用脚本内的函数,通过Value创建了参数,但是不管我是否手动free,都会遇到退出时gc泄露的情况。 请问我该怎么处理? 还有一些情况,我一些情况下无法用立即数传回需要的对象。用全局对象就可以读出来。请问有什么信息可以给我吗?

wildfire810 avatar Jul 19 '24 13:07 wildfire810

问题1 :

我在生成字节码时,需要根据脚本载入所有模块,所以是否可以暴露载入模块的回调?

在LoadModule的实现中, https://github.com/buke/quickjs-go/blob/main/context.go#L383 ,此处cVal 实际返回的是promise 对象,经过C.js_std_await 处理后返回模块对象。你所指的是直接暴露cVal 对象吗?

func (ctx *Context) LoadModule(code string, moduleName string) (Value, error) {
	codePtr := C.CString(code)
	defer C.free(unsafe.Pointer(codePtr))

	filenamePtr := C.CString(moduleName)
	defer C.free(unsafe.Pointer(filenamePtr))

	cFlag := C.JS_EVAL_TYPE_MODULE | C.JS_EVAL_FLAG_COMPILE_ONLY
	cVal := C.JS_Eval(ctx.ref, codePtr, C.size_t(len(code)), filenamePtr, C.int(cFlag))
	if C.ValueGetTag(cVal) != C.JS_TAG_MODULE {
		return ctx.Null(), fmt.Errorf("not a module")
	}
	if C.JS_ResolveModule(ctx.ref, cVal) != 0 {
		C.JS_FreeValue(ctx.ref, cVal)
		return ctx.Null(), fmt.Errorf("resolve module failed")
	}
	C.js_module_set_import_meta(ctx.ref, cVal, 0, 1)
	cVal = C.js_std_await(ctx.ref, cVal) // 此处cVal 实际返回的是promise 对象,经过C.js_std_await 处理后返回模块对象

	return Value{ctx: ctx, ref: cVal}, nil
}

问题2:

另外,我想要调用脚本内的函数,通过Value创建了参数,但是不管我是否手动free,都会遇到退出时gc泄露的情况。 请问我该怎么处理?

肯定是有某个对象没有free导致,如果方便的话还请贴上代码一起探讨。

问题3:

还有一些情况,我一些情况下无法用立即数传回需要的对象。用全局对象就可以读出来。请问有什么信息可以给我吗?

我在编写LoadModule的测试用例也发现了这种情况,如 https://github.com/buke/quickjs-go/blob/main/quickjs_test.go#L807,猜测是模块加载quickjs 内部使用了worker 来加载,未立刻返回对象值所致。

buke avatar Jul 20 '24 12:07 buke