В JavaScript-платформе Bun добавлена поддержка вызова кода на языке Си

В платформе Bun, развиваемой в качестве альтернативы Node.js и предназначенной для обособленного выполнения приложений, написанных на языках JavaScript, JSX и TypeScript, реализована экспериментальная возможность компиляции и выполнения обработчиков, написанных на языке Си. Ранее для вызова низкоуровневого кода требовалось либо создавать N-API-плагины к движку V8, либо компилировать код в формат WebAssembly (WASM/WASI), что усложняло разработку и накладывало определённые ограничения. Теперь код на языке Си можно напрямую встраивать в JavaScript и компилировать на лету с использованием компилятора TinyCC, а также подключать динамически связываемые библиотеки.


   import { cc } from "bun:ffi";

   export const {
     symbols: { hello },
   } = cc({
     source: "./hello.c",
     symbols: {
       hello: {
         returns: "void",
         args: [],
       },
     },
   });

   hello();

Для работы с языком Си используется прослойка bun:ffi, которая компилирует исходный код в машинные инструкции, подставляет его в память при выполнении и обеспечивает автоматическую конвертацию типов данных между JavaScript и Си. Отмечается, что накладные расходы при обращении к скомпилированному Си-коду сведены к минимуму и приводят к задержке на уровне около 2 наносекунд на каждый вызов внешних Си-функций. В качестве примера показано как можно напрямую обращаться к библиотекам FFmpeg для преобразования коротких видео — за счёт исключения таких операций как ответвление отдельного процесса и выделения памяти для каждого видео, общее время выполнения тестового задания при использовании bun:ffi удалось сократить в три раза.

Более того, в выпуске Bun 1.1.29 для кода на языке Си добавлена поддержка N-API (napi), благодаря которому написанные на языке Си-обработчики могут возвращать объекты, строки, массивы и другие не примитивные значения JavaScript, помимо свойственных языку Си типов, таких как int и float.
Механизм вызова обработчиков на языке Си действует и при динамической загрузке любых библиотек с C ABI, независимо от того, на каком языке они написаны изначально (C++, Rust, Zig и т.п.), что позволяет вызывать из JavaScript-кода предоставляемые данными библиотеками функции без отдельной стадии пересборки. Например, теперь можно обращаться из JavaScript к системным API.

Источник: http://www.opennet.ru/opennews/art.shtml?num=61915