QuickJS runtime с лимитами

HPDFQuickJS и HPDFQuickJSStatic открывают одинаковый контролируемый приложением API вычисления JavaScript на Win32 и Win64

Выбор режима развёртывания

DLL-биндинг принимает явный путь, значение окружения HOTPDF_QUICKJS_DLL или платформенный каталог, найденный ниже предка исполняемого файла

Сборки по умолчанию кладут bridge в Lib\thirdparty\QuickJS\bin\Win32\quickjs.dll или Lib\thirdparty\QuickJS\bin\Win64\quickjs.dll

На Linux x86-64 HPDFQuickJS загружает нативный bridge libhpdfquickjs.so, собранный скриптом tools/Build-HotPDFQuickJSLinux.sh; явный путь и переменная окружения следуют тем же правилам владения и 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 и сохраняет Unicode при возврате Delphi-строки

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, скрипт UTF-8 на 1 MiB, одна секунда настенного времени и миллион проверок прерывания

Статический runtime Win32 ограничивает запрошенный стековый бюджет (ноль и выше) сверху значением 48 KiB, чтобы оставаться в пределах безопасной для компилятора рекурсии; режимы DLL и Win64 берут запрошенное значение напрямую

Лимиты памяти и стека действуют на весь runtime, а лимиты скрипта, времени и прерываний применяются к каждому вычислению

Статусы и восстановление

Отклонённое или прерванное вычисление очищает ожидающее исключение и буферы, поэтому тот же экземпляр движка может исполнить следующий валидный скрипт

Экземпляр движка не реентерабелен: один экземпляр на каждого конкурентного воркера

Скриптинг XFA-форм

Движок flattening XFA переиспользует этот runtime, только если явно установлен THotPDF.XFAJavaScriptEnabled; он даёт ограниченный data facade, нативные typed arrays, проверенные запросы экземпляров и не даёт объектов file, process, browser или network

TXFAFormScriptOptions.JavaScriptEvaluator может адаптировать статический runtime, не заставляя тянуть статические QuickJS-объекты в каждое приложение HotPDF

См. Bounded XFA FormCalc and JavaScript

Воспроизводимая сборка runtime

powershell -ExecutionPolicy Bypass -File Lib\thirdparty\build-quickjs-runtime.ps1

Скрипт сборки создаёт оба набора статических объектов и оба bridge DLL из комплектного исходника, после чего runtime-матрица компилирует и прогоняет static- и DLL-пробы для Win32 и Win64