QuickJS runtime с лимитами
HPDFQuickJS и HPDFQuickJSStatic открывают одинаковый контролируемый приложением API вычисления JavaScript на Win32 и Win64
Выбор режима развёртывания
HPDFQuickJSзагружает ABI-нейтральный bridgequickjs.dllи держит значения QuickJS внутри C-кодаHPDFQuickJSStaticлинкует платформенные OMF-объекты в приложение и не требует runtime DLL- Не включайте оба модуля в одну программу — они публикуют одинаковые публичные имена типов
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, а лимиты скрипта, времени и прерываний применяются к каждому вычислению
Статусы и восстановление
qjsSuccess— результат сконвертированqjsScriptError— синтаксические ошибки, брошенные значения и сбои конвертацииqjsTimeLimitиqjsInterruptLimitразличают два бюджета выполненияqjsBusy,qjsInvalidArgument,qjsResourceErrorиqjsUnavailableсохраняют инфраструктурные сбои
Отклонённое или прерванное вычисление очищает ожидающее исключение и буферы, поэтому тот же экземпляр движка может исполнить следующий валидный скрипт
Экземпляр движка не реентерабелен: один экземпляр на каждого конкурентного воркера
Скриптинг 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