有界 QuickJS 运行时

HPDFQuickJS 和 HPDFQuickJSStatic 在 Win32 和 Win64 上暴露相同的应用程序控制 JavaScript 求值 API

选择部署模式

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 模式直接遵循请求值

内存和栈限制是运行时范围的,而脚本、时间和中断限制应用于每次求值

状态与恢复

被拒绝或中断的求值清除其挂起的异常和缓冲区,因此同一引擎实例可以执行后续有效脚本

一个引擎实例不可重入;每个并发工作进程使用一个实例

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 探针