有界 QuickJS 运行时
HPDFQuickJS 和 HPDFQuickJSStatic 在 Win32 和 Win64 上暴露相同的应用程序控制 JavaScript 求值 API
选择部署模式
HPDFQuickJS加载 ABI 中立的quickjs.dll桥接器并将 QuickJS 值保留在 C 代码内HPDFQuickJSStatic将平台特定的 OMF 对象链接到应用程序,无需运行时 DLL- 不要在一个程序中同时包含两个单元,因为它们发布相同的公共类型名称
DLL 绑定接受显式路径、HOTPDF_QUICKJS_DLL 环境值或可执行文件祖先下方找到的平台目录
默认构建将桥接器放在 Lib\thirdparty\QuickJS\bin\Win32\quickjs.dll 或 Lib\thirdparty\QuickJS\bin\Win64\quickjs.dll
在 Linux x86-64 上,HPDFQuickJS 加载由 tools/Build-HotPDFQuickJSLinux.sh 构建的原生 libhpdfquickjs.so 桥接器;显式路径和环境变量遵循同样的持有与 ABI 规则
Linux 默认探测可执行文件所在目录和 Lib/thirdparty/QuickJS/bin/Linux64;原生静态 OMF 部署仍然是 Windows 专属
求值脚本
uses
HPDFQuickJS;
var
Engine: THPDFQuickJS;
EvalResult: THPDFQuickJSResult;
begin
Engine := THPDFQuickJS.Create;
try
if not Engine.Available then
raise Exception.Create(Engine.LoadError);
EvalResult := Engine.Eval('JSON.stringify([1, 2, 3].map(x => x * 2))');
if not EvalResult.Success then
raise Exception.Create(EvalResult.Error);
finally
Engine.Free;
end;
end;
Eval 将最终 JavaScript 值转换为 UTF-8 文本,并在返回 Delphi 字符串时保留 Unicode
EvalInt 和 EvalFloat 添加严格数值转换,而不跨 ABI 边界暴露引擎值
执行限制
Limits := THPDFQuickJSLimits.CreateDefault;
Limits.MemoryBytes := 32 * 1024 * 1024;
Limits.StackBytes := 64 * 1024;
Limits.MaxScriptBytes := 256 * 1024;
Limits.TimeoutMs := 250;
Limits.MaxInterruptChecks := 250000;
Engine := THPDFQuickJS.Create(Limits);
默认允许 64 MiB 引擎内存、64 KiB 栈、1 MiB UTF-8 脚本、一秒墙钟时间和一百万次中断检查
Win32 静态运行时将零或更大的请求栈预算限制在 48 KiB,以保持在编译器安全递归边界内;DLL 和 Win64 模式直接遵循请求值
内存和栈限制是运行时范围的,而脚本、时间和中断限制应用于每次求值
状态与恢复
qjsSuccess报告转换结果qjsScriptError报告语法错误、抛出值和转换失败qjsTimeLimit和qjsInterruptLimit区分两个执行预算qjsBusy、qjsInvalidArgument、qjsResourceError和qjsUnavailable保留基础设施失败
被拒绝或中断的求值清除其挂起的异常和缓冲区,因此同一引擎实例可以执行后续有效脚本
一个引擎实例不可重入;每个并发工作进程使用一个实例
XFA 表单脚本
XFA 展平引擎只在显式设置 THotPDF.XFAJavaScriptEnabled 时重用此运行时;它提供受限数据门面、原生类型化数组、验证的实例请求,并且没有文件、进程、浏览器或网络对象
TXFAFormScriptOptions.JavaScriptEvaluator 可以适配静态运行时,而无需将静态 QuickJS 对象强加给每个 HotPDF 应用程序
请参阅 有界 XFA FormCalc 与 JavaScript
可复现运行时构建
powershell -ExecutionPolicy Bypass -File Lib\thirdparty\build-quickjs-runtime.ps1
构建脚本从捆绑源产生两个静态对象集和两个桥接 DLL,然后运行时矩阵为 Win32 和 Win64 编译并练习静态和 DLL 探针