Релиз Cheerp 1.3, компилятора C++ в JavaScript
После года разработки состоялся релиз Cheerp 1.3 (бывший Duetto), открытого инструментария для разработки клиентских и серверных web-приложений на языке C++, а также для портирования существующих C++ программ для работы в Web-браузере. Код распространяется под свободной лицензией UI/NCSA, также используемой в проекте LLVM. Библиотеки поставляются под лицензией GPLv2+.
По своей сути Cheerp напоминает систему Emscripten и также использует наработки LLVM для обеспечения компиляции кода C++ в представление на языке JavaScript. Ключевым отличием Cheerp от Emscripten является ориентация на достижении более высокой производительности получаемого JavaScript-кода и предоставление средств для использования из С++ программ всех возможностей DOM, браузерного API и HTML5, в том числе WebGL. Cheerp не пытается, как Emscripten, эмулировать традиционное адресное пространство при помощи типизированных массивов, а обеспечивает прямой маппинг C++ объектов в объекты JavaScript, что позволяет снизить потребление памяти, так как сборщик мусора JavaScript имеет возможность удалять неиспользуемые объекты. Cheerp также поддерживает использование стандартных библиотек libc и libc++, и позволяет применять инструменты сборки cmake/autotool.
По поставленным перед проектом задачам Cheerp позиционируется как платформа для создания интегрированных клиент/серверных web-приложений на языке C++. В существующей практике, обычно используется выполняемый в браузере фронтэнд, написанный на языке JavaScript или компилируемый в JavaScript из Coffe&173;Script, Microsoft Type&173;Script, Google Dart, Google GWT, с раздельной серверной частью на языках PHP, Python, Ruby или JavaScript/node.js. Cheerp предоставляет средства для создания целостных web-приложений на языке C++, в которых бэкенд и фронтэнд поддерживаются в единой кодовой базе. В процессе компиляции серверная часть компилируется в нативный код, а интерфейс преобразуется в JavaScript-представление. Отладка всех компонентов проекта, в том числе преобразуемых в JavaScript, осуществляется по исходным текстам на языке C++ с использованием технологии Source Map (при возникновении ошибки можно увидеть участок кода на C++, поддерживается установка точек останова в коде C++ и построчного пошагового выполнения С++ кода).
В новом выпуске отмечено значительное увеличение производительности кода, скомпилированного в Cheerp. Значительного ускорения удалось добиться не только оптимизацией кода компилятора, но и благодаря совместной работе с разработчиками движка SpiderMonkey, используемого в Firefox. В итоге, по сравнению с прошлым выпуском код проектов на языке C++, скомпилированный в JavaScript при помощи Cheerp 1.3, стал выполняться в браузере в среднем на 11% быстрее. В ресурсоемких тестах выигрыш составляет около 25%, в тесте на основе физического движка Bullet - 33%, а в тесте Box2D - 20%.
При сравнении со скоростью выполнения нативного кода, собранное в Cheerp представление на JavaScript работает медленнее приложения сокмпилированного в машинный код в среднем в 2.5 раза. Если сузить выборку до крупных тестов (Bullet, Box2D), то в 3.7 раза.
Результирующий размер сгенерированного в новой версии кода стал в среднем на 25% меньше, чем при использовании Cheerp 1.2, и на 5-40% меньше по сравнению с результатами компиляции в Emscripten.
В новой версии также проведена работа по улучшению работы генератора кода, расширению спектра поддерживаемых конструкций C++ и улучшению переносимости с JavaScript. Улучшена работа алгоритма PreExecuter, обеспечивающего упреждающее выполнение порций кода на этапе компиляции. Например, в текущей реализации PreExecuter используется для исключения запуска во время выполнения JavaScript консрукторов, используемых для инициализации глобальных объектов C++, которые можно вычислить на этапе компиляции и добавить в JavaScript в виде инициализированного среза памяти. В новой версии подобный метод упреждающей инициализации стал доступен для сложныъ структур данных.
В области переносимости между C++ и JavaScript/Web API улучшена поддержка тега "[[cheerp::jsexport]]", который теперь может применяться для отдельных функций, а не только для классов, что позволяет представить в JavaScript любую часть приложения C++. В новой версии также сняты ограничения по определению глобальных переменных в пространстве имен клиента, улучшена поддержка вариативных аргументов и расширена поддержка объединений (union). Для упрощения выявления некорректно сгенерированного JavaScript-кода в компилятор добавлены две новые опции (-cheerp-bounds-check и -cheerp-defined-members-check) для выполнения дополнительных проверок.