代码执行方式
本节解释JS_Eval
的最后一个参数flag
的含义。以及如何使用编译后的JS二进制代码执行。
二进制代码执行的例子在这里
代码执行方式
有两种Type:
JS_EVAL_TYPE_GLOBAL
:全局模式执行(默认的),即所有代码都在全局模式下执行。某些代码中定义的对象可以在其他代码中使用JS_EVAL_TYPE_MODULE
:以模块模式执行。代码被视为模块(类似nodejs模块),并且可以使用模块导入语法import * from 'Module'
和四种Flag(可组合):
JS_EVAL_FLAG_STRICT
:以严格模式执行(相当于JS代码中写use strict
,但QuickJS会忽略你写的,所以你只能通过指定此Flag来执行严格模式)JS_EVAL_FLAG_COMPILE_ONLY
:只是编译,不运行JS_EVAL_FALG_BACKTRACE_BARRIER
:不要在出错时的栈回溯中包含此代码执行之前的堆栈帧JS_EVAL_FLAG_ASYNC
:只能搭配JS_EVAL_TYPE_GLOBAL
。代码以异步执行,JS_Eval
返回一个Promise,需要等待。
以二进制方式执行代码
QuickJS有个编译器qjsc
可以将JS代码编译成二进制,这样减少了代码体积,在运行时速度也会更快。
使用qjsc
编译我们的代码:
qjsc -b -n "main.js" -o output.qjs main.js
-b
代表编译成二进制而不是C代码(没错可以编译成C代码,直接嵌入C文件中执行)-n
指定编译之后的脚本名称(用于调试,在抛出异常时包含在stack traces中)-o
指定编译的结果文件
最后的参数是要编译的代码文件。
然后在C++代码中执行:
JSValue obj = JS_ReadObject(ctx, (uint8_t*)content.data(), content.size(), JS_READ_OBJ_BYTECODE);
JSValue result = JS_EvalFunction(ctx, obj);
首先使用JS_ReadObject
从二进制代码中读取JSValue
,然后使用JS_EvalFunction
执行。