Привет, Хабр! Представляю вашему вниманию перевод статьи «Back To The Future With WebAssembly» автора Attila Vago.
В 2011 году я написал свою первую независимую строку кода не на HTML (с ним я работал в 2007 году), и она была написана на том самом старом добром С, который преподавал профессор Дэвид Дж. Малан из Гарвардского университета. Он навсегда останется моим вдохновителем не только на изучение программирования, но и на программное мышление. Также запомнилось то, что приготовить бутерброд с арахисовым маслом просто для меня, однако это невероятно сложная задача для компьютера и одинаково трудная для человека, притворяющегося компьютером.
Если вы посмотрели видео, хотя бы первые 18 минут (я знаю, что это долго, но программирование требует времени), то Вы поймете, почему по сей день C близок моему сердцу. К моему разочарованию, я так и не обучился ему, потому что, давайте посмотрим правде в глаза, для веб-разработчика C – это наименьший из приоритетов. У меня никогда не было реальной причины погружаться глубоко в этот язык, несмотря на покупку бесчисленных курсов Udemy и книг по C, я никогда не прикасался к ним (держите свои осуждающие взгляды при себе, Вы делали также) или лгать себе, что если я куплю смарт часы Pebble, которые работают на C, то обязательно напишу для них код. Да, точно! Ни одна из этих причин не была достаточно веской.
WebAssembly (сокращенно Wasm) – это бинарный формат инструкций для стековой виртуальной машины.
«Wasm разработан как переносимая платформа для компиляции языков высокого уровня, таких как C/C++/Rust, что позволяет развертывать в интернете клиентские и серверные приложения»– любезно объясняет webassembly.org
Иными словами, вышеизложенное означает, что Вы можете писать модули, которые работают в интернете, в браузере/сервере, но написаны на таких языках, как C, скомпилированы в двоичный файл и поэтому невероятно быстры, поскольку они работают непосредственно на аппаратном обеспечении машины. В сравнении с ними, скриптовые языки, такие как JavaScript, имеют несколько уровней абстракции между кодом и оборудованием, что, среди прочего, делает их медленными. Конечно, это не всегда имеет значение, и каждый из них имеет свое место в программе или даже веб-экосистеме.
Исходя из этого, Wasm по строению (изначально) поддерживает только целые числа и числа с плавающей точкой, что дает большую вычислительную мощность и, следовательно, часто используется для реализаций типа canvas. Важно понимать, что WebAssembly не представляет угрозы для JavaScript — во всяком случае, пока — и, как вы увидите далее в этой статье, C и JavaScript могут на самом деле жить очень счастливо в одном проекте и могут запускать код друг друга. Да, что-то вроде того.
А теперь держитесь! Я знаю, что говорю. Нельзя произносить такие вещи, как ”запуск C в JS и наоборот", и ожидать, что мир не отреагирует. Как бы странно это ни звучало, я не обманываю. Оказывается, Emscripten — это цепочка инструментов для компиляции в asm.js и WebAssembly, спроектированные с использованием LLVM (Боже мой, половину этих вещей я узнал, пока набирал текст статьи), что позволяет запускать C и C++ в интернете на почти родной скорости без плагинов.
Хорошо, вот то, что необходимо из этого выделить для себя. Emscripten поможет Вам скомпилировать код, написанный на C в WebAssembly, предоставив дополнительные инструменты для облегчения нагрузки на разработчика, когда дело доходит до общения между двумя языками, и поможет запустить Wasm в Вашем веб-проекте. Базовая команда компиляции Emscripten выглядит следующим образом:
emcc lib/strings.c -s WASM=1 -o public/strings.js
emcc lib/imports.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -o public/imports.js
Настройка Emscripten не самая простая вещь, но и не запуск ракеты. Единственное, что усложняет настройку – это то, что она имеет множество зависимостей, таких как Python, Node, xCode, Git и cMake. Все инструкции можно найти на странице установки и легко следовать им.
Поэтому Emscripten:
Примечание: Вам не нужен Emscripten для генерации Wasm, поскольку во все новые браузеры встроен API для поддержки Wasm в том же окне, что выполняет Emscripten в качестве верхнего слоя, что делает жизнь разработчика намного легче. Например, Emscripten будет подстраивать объем памяти под Вас, что может быть утомительным через С.
Вы знаете, как говорится «строка кода стоит тысячи слов», – ОК, это прерогатива рассказчика и все такое, поэтому без лишних слов давайте взглянем на какой-нибудь реальный код. Комментарий не по теме: в тот день я не мог преодолеть синтаксис C. Он не компилировался половину времени, потому что мой код был бы шатким. И через восемь лет я такой: «Да это же похоже на JavaScript”.
Ребята, если кто-то начнет видеть код C в моем React, просто верните меня к реальности, хорошо?
Еще немного не по теме, вот вам действующий код на C:
И, соответственно, на JavaScript:
ОК, что именно происходит в этих файлах? На самом деле довольно много, так что я перечислю.
Предсказуемый результат вышесказанного таков:
Как и во всяком коде, в WebAssembly также есть порядок выполнения. Не возимся с очередью! Порядок в этом случае является стандартным для С порядком. Все запускается в Main() и всякий раз, когда main() готов, готов и Wasm. Однако что произойдет, если вам нужна статическая функция для вызова во время выполнения? Ну, просто немного синтаксического сахара Emscripten, и все идет как по маслу:
Это хорошо написанный код, особенно простые штуки, проиллюстрированные в предыдущих разделах, но мы все знаем, что реальный мир намного больше, чем “Hello World”, и половина времени каждого разработчика тратится на то, чтобы выяснить, почему код не делает то, что должен. Баги просто неизбежны и в каком-то смысле являются частью жизни.
При запуске C в JS или любого Wasm, если на то пошло, все может стать еще более удручающим. К счастью, Emscripten снова приходит на помощь, предоставляя два очень полезных метода отладки:
// browser debugger gets triggered
emscripten_debugger();
// browser console warning with stack-trace
emscripten_log(EM_LOG_WARN, “‘param’ your message”);
emrun --port 7777 --no_browser public/index.html
Now listening at http://localhost:7777/
Хорошо, двумя махами… приведенный выше пример работает, но следующий работает лучше, что объясняет показанная ошибкой.
<b>// compile as emrun project
emcc lib/strings.c -s WASM=1 --emrun -o public/index.html
// run the emrun server again
emrun --port 7777 --no_browser public/index.html</b>
Я просто оставлю это так. Изучая WebAssembly, я отметил День Святого Патрика и следующий день. Не совсем уверен, что будет дальше, но меня это взволновало достаточно, чтобы сидеть перед монитором в течение двух дней, пытаясь вникнуть в основы WebAssebly, и это должно что-то значить, верно? Это самый код на C, который я написал с 2011 года, и он отлично себя чувствует. Я думаю, что у WebAssembly есть реальное будущее, но я не уверен, что он полностью захватит сеть и убьет JS, как проповедуют некоторые. А Вы как думаете?
К сожалению, не доступен сервер mySQL