В 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.

Release. Ссылка here.