Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

代码执行方式

本节解释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执行。