Comments 28
Прекрасный пошаговый walkthrough, спасибо.
Ребята, Вы что, серьезно, считаете «перекомпиляцию» байт-кода в код на js «портированием»? Вы хоть видели код, который получился — будет он вообще работать-то в браузерной песочнице на реальных объемах данных ?!
Я понимаю, если бы был только объектный код, но у Вас же есть исходник на С/С++!
Я понимаю, если бы был только объектный код, но у Вас же есть исходник на С/С++!
Так многое было портирована на js, и ничего, работает.
А, простите — Зачем?
Нет, можно, конечно, но я подозреваю что здесь речь всё таки не совсем о браузере.
Нет, можно, конечно, но я подозреваю что здесь речь всё таки не совсем о браузере.
Мне кажется emscripten это проект больше на будущее. Он развивает экосистему LLVM и JavaScript. А генеренный код можно использовать например в nodejs. На данном этапе xml.js работает заметно медленнее своего нативного аналога, но я надеюсь что в будущем оптимизирующие возможности emscripten тоже подрастут.
Спасибо, действительно – Very Nice.
+1
+1
Вот и дожили до момента, когда плюсовые либы портируют в js :)
Сразу возникает вопрос: а где Emscripten работает — только под Linux?
В Википедии я не нашёл списка поддерживаемых операционных систем, в README на Гитхабе и в тамошней викина заглавной странице — тоже не нашёл.
Только добравшисьдо FAQ, насилу прочёл, что работает в Windows, OS X и Linux, хотя автор проверяет его только на Linux. В пособии также сказано, что под Windows требуется Cygwin для «make».
В Википедии я не нашёл списка поддерживаемых операционных систем, в README на Гитхабе и в тамошней вики
Только добравшись
Я ничего не понял
У вас была программа (xmllint), которая в качестве аргументов командной строки берет имена xml и xcd файлов и проверяет соответствие xml xcd. Результат проверки выводится в консоль.
В результате всех этих манипуляций вы (или автор оригинальной статьи) получили js-файл с единственной функцией ValidateXML; в качестве параметров она получает имена файлов, в качестве результата выдает то же самое, что и xmllint
Если все так, то
а) почему везде написано «портирование библиотеки», когда на самом деле портируется программа, использующая библиотеку
б) возможно ли все-таки портировать именно libxml так, чтобы получить нечто вроде github.com/polotek/libxmljs но на чистом js без зависимостей?
У вас была программа (xmllint), которая в качестве аргументов командной строки берет имена xml и xcd файлов и проверяет соответствие xml xcd. Результат проверки выводится в консоль.
В результате всех этих манипуляций вы (или автор оригинальной статьи) получили js-файл с единственной функцией ValidateXML; в качестве параметров она получает имена файлов, в качестве результата выдает то же самое, что и xmllint
Если все так, то
а) почему везде написано «портирование библиотеки», когда на самом деле портируется программа, использующая библиотеку
б) возможно ли все-таки портировать именно libxml так, чтобы получить нечто вроде github.com/polotek/libxmljs но на чистом js без зависимостей?
Библиотека — libxml, программа — xmllint.
Выше уже пробегала мысль что это не есть портирование в чистом виде. Скорее это транслирование LLVM байт-кода в JavaScript. По какой причине в оригинальной статье используется термин портирование мне не известно, для себя я счел это не важным. Скорее это вопрос терминологии.
А суть что происходит вы уловили правильно. Это лишь общая схема показывающая как можно выдернуть конкретную функцию из libxml.
Для того что бы получить порт библиотеки нужно написать обертку для вызова каждой конкретной функции из libxml2. Выполнив команду:
Построится файл libxml2.js который будет содержать функции соответствующих статических библиотек, эти функции можно напрямую вызывать из JavaScript кода. Правда делается это не очень красиво, как-то так:
Пример показывает как обернуть c-функцию, подробнее тут.
А суть что происходит вы уловили правильно. Это лишь общая схема показывающая как можно выдернуть конкретную функцию из libxml.
Для того что бы получить порт библиотеки нужно написать обертку для вызова каждой конкретной функции из libxml2. Выполнив команду:
~/path/emscripten/emcc .libs/libxml2.a ../zlib-1.2.7/libz.a -o libxml2.js
Построится файл libxml2.js который будет содержать функции соответствующих статических библиотек, эти функции можно напрямую вызывать из JavaScript кода. Правда делается это не очень красиво, как-то так:
int_sqrt = cwrap('int_sqrt', 'number', ['number'])
int_sqrt(12)
Пример показывает как обернуть c-функцию, подробнее тут.
Какая разница каким образом было сделано портирование? Портирование нацелено на результат, а не процесс.
Разница примерно такая же, как результат перевода человеком или каким-нибудь «промтом». Вроде бы и всё понятно, но местами коряво, местами смешно.
Нет. Языки программирования имеют очень жесткую семантику и синтаксис в отличии от языков на которых мы говорим.
Это каким-то образом мешает писать говнокод? Нет.
Это мешает писать глючные программы? Ни капли.
Тогда при чём тут жёсткая семантика?
Можно написать очень понятный и чёткий код, который и человек хорошо прочитает, и интерпретатор/компилятор хорошо оптимизируют.
А можно написать нечто ужасное. Вот итог работы автоматических трансляторов (особенно через несколько этапов трансляции), программ оптимизированных совсем не под конечную платформу — и есть такой ужас.
При этом без возможности нормально исправить баг вылезший на неродной платформе.
Это мешает писать глючные программы? Ни капли.
Тогда при чём тут жёсткая семантика?
Можно написать очень понятный и чёткий код, который и человек хорошо прочитает, и интерпретатор/компилятор хорошо оптимизируют.
А можно написать нечто ужасное. Вот итог работы автоматических трансляторов (особенно через несколько этапов трансляции), программ оптимизированных совсем не под конечную платформу — и есть такой ужас.
При этом без возможности нормально исправить баг вылезший на неродной платформе.
Цикл for будет всегда циклом for, а не будет менять свое значение в зависимости от ситуации и происхождения программиста. Так понятнее?
Программа состоит не только из циклов for. И есть ситуации когда то, что эффективно в оригинале, транслированное становится очень неэффективным. И есть конструкции, имеющиеся в оригинальной платформе, но эмулируемые на конечной. Или в Вашем понимании вся трансляция сводится к замене одного синтаксиса на другой? Если бы всё было так просто — не было бы такого количества языков, а была бы масса препроцессоров для одного.
Хорошо, попробую объяснить свою точку зрения на практическом примере: великолепный проект repl.it/#
Возьмём питон. Вот он транслированный в javascript: raw.github.com/replit/empythoned/master/dist/python.opt.js
Задача: впилить сюда интеграцию с браузером и DOM страницы.
Теперь Вы понимаете разницу между портировать и просто транслировать? Портированный — был бы читабельным аналогом оригинального кода и можно было бы легко найти соответствия и оперировать ими, можно было бы легко изучать структуру. Транслрованный — просто мешанина однообразных символов с точки зрения человека. Про неоптимальность этого кода для целевой платформы — я уже тоже упоминал.
Да, это работает. Но, сделать с этим что-то вменяемое по целесообразной цене — нереально.
Возьмём питон. Вот он транслированный в javascript: raw.github.com/replit/empythoned/master/dist/python.opt.js
Задача: впилить сюда интеграцию с браузером и DOM страницы.
Теперь Вы понимаете разницу между портировать и просто транслировать? Портированный — был бы читабельным аналогом оригинального кода и можно было бы легко найти соответствия и оперировать ими, можно было бы легко изучать структуру. Транслрованный — просто мешанина однообразных символов с точки зрения человека. Про неоптимальность этого кода для целевой платформы — я уже тоже упоминал.
Да, это работает. Но, сделать с этим что-то вменяемое по целесообразной цене — нереально.
А вы понимаете, что транслирование это только первый этап?
Так же, если результат тралирования работает без доработок — было выполнено портирование. Понимаете?
Sign up to leave a comment.
Портируем C/C++ библиотеку на JavaScript (xml.js)