Pull to refresh

Comments 19

Не знаком с WebAssembly, и поэтому есть вопросы:


WebAssembly — кроссплатформенный байткод

Разве это не позволяет интерпретирующему использовать всю ту же JIT-компиляцию?


wasm не привязан к конкретному языку (или группе языков, с учётом Scala и Kotlin)

JVM тоже не привязана к Java, она понимает свой байткод, в который могут компилироваться и другие языки (выше озвученные например). Группе языков? Есть интерпретаторы Python/Ruby/etc, но да, всё же это интерпретатор в интерпретаторе.
Или я что-то не понимаю?


JVM достаточно массивна

Java 9 не спасёт ситуацию?


Кстати, гуглятся интерпретаторы WebAssembly под .NET и JVM.

Разве это не позволяет интерпретирующему использовать всю ту же JIT-компиляцию?
JIT-компиляция замечательна, когда на неё есть ресурсы. У FGPA и большей части мобилок их нет. С WebAssembly во время AOT-компиляции можно сделать значительно более сложные и затратные компиляции, чем позволяют ограничения по времени и ресурсам при JIT. Аналогию можно провести с asm.js, который по сути есть AOT-скомпилированный Javascript. Или с LuaJIT, который, в пику названию, предлагает возможность распространять AOT-скомпилированные модули. WebAssembly — шаг дальше в том же направлении.

JVM привязана больше к инфраструктуре, а не к языку. Были причины, почему Java в своё время не заняла нишу WebAssembly, несмотря на попытки. И воз поныне там же. Подробнее можно здесь.

Java 9 не спасёт ситуацию?
Нет. Например, вам нужно сделать исполняемые модули с исключительно математическими функциями. На WebAssembly вы можете сделать подмножество, которое умеет только в математику. С JVM придётся тянуть рантайм, вне зависимости от версии Java.

Кстати, гуглятся интерпретаторы WebAssembly под .NET и JVM.
Так точно. Байткод и интерпретатор для WebAssembly MVP очень простые, буквально за пару вечеров можно написать. Это ещё одна причина, почему у технологии есть все шансы развиться. Порог входа намного ниже, чем в большинство системных разработок. Вся сложность на уровне компиляторов и средств разработки. Мы взяли интерпретатор WABT из соображений портируемости: С/С++ достаточно просто запускается практически везде.

Фича как раз в том, что собранные модули можно запускать на любом интерпретаторе любой конструкции. В том числе, нативном, браузерном, или построенном поверх JVM и .NET.
Были причины, почему Java в своё время не заняла нишу WebAssembly, несмотря на попытки.
Причина, собственно, одна: Ларри сильно денег хотел.

Все недостатки CLR/C# и JVM/Java можно было бы исправить — но только совместными усилиями. А их владельнцы хотели их полностью контролировать, «бить по рукам» всех конкуретном и «снимать сливки».

В результате «сливок» никому не досталось, и подходы, основанные на JVM (а это не только апплеты — были и другие интересные идеи) и подходы, основанные на CRL (Silverlight и прочее) оказались выкинутыми «на свалку истории», а мы остались с JavaScript'ом и, вот теперь уже, пытаемся переизобрести всё в третий раз…

Посмотрим, что выйдет…
Причина, собственно, одна: Ларри сильно денег хотел.

Дело не в этом, всё это попросту не может быть альтернативой — ведь по-сути оно не отличается от js. Суть васма именно в том, чтобы не быть привязанным к какой-то платформе, языку — он на том и асм.

В результате «сливок» никому не досталось, и подходы, основанные на JVM (а это не только апплеты — были и другие интересные идеи) и подходы, основанные на CRL (Silverlight и прочее) оказались выкинутыми «на свалку истории», а мы остались с JavaScript'ом и, вот теперь уже, пытаемся переизобрести всё в третий раз…

Неверно, нигде и никак не переизобретаются все эти «идеи» — они умерли потому, что никому не нужны.

Причина проста — снизу должно быть то, что может быть снизу. На лоулевел языке можно реализовать хайлевел, а вот наоборот нет. К языку без ГЦ может прикрутить ГЦ, а вот наоборот нет. Именно в этом проблема — жаваскрипт. Жава ничем не отличается от жаваскрипта в этом плане. И нет смысла менять шило на мыло.

Асмжс и упёрся в проблемы жаваскрипта. Прозрачное взаимодействие с жс, текст, кастыли. Всё это никому не нужно. Зачем кому-то нужно превращать бинарь в текст, типизацию в синтаксические кастыли, если можно проще всё гонять в исходной форме?

И причина, как я уже говорил, не в самой форме, а в том, что это более «совершенная форма». Никому не нужно по сети гонять текст, никому не нужен запрос-ответ, никому всё это не нужно. Вернее нужно тем, кто к этому привык, но это субъективные желания.

Хочешь текст? Пожалуйста — бинарный проток это позволяет, а вот наоборот нет. Хочешь себе запрос-ответ — пожалуйста, всё это реализуется на базе более общего протокола.

Именно в этом суть — более «совершенное» вытесняет менее совершенное и ограниченное, ведь ограничить что-то всегда можно, а вот расширить — нет.
К языку без ГЦ может прикрутить ГЦ, а вот наоборот нет.
Если бы. Дело в том, что программирование в системе с ГЦ и без ГЦ — очень сильно разные вещи. При этом в системе с ГЦ можно программировать, как в системе без ГЦ — и это часто делается (кладём всё на массивы и «ручками» управляем из содержимым), а вот наоборот — фиг. Много вы видели систем на C++ с ГЦ? Не на «сбоку прилепленным» C# (Java, Lisp — нужное подчеркнуть), а на С++?

Именно в этом суть — более «совершенное» вытесняет менее совершенное и ограниченное, ведь ограничить что-то всегда можно, а вот расширить — нет.
Вопрос только в том, что вы понимаете под словом «совершенное». А то пока получается тавтология: если технология А вытесняет технологию Б, то технология А — более совершенна… возможно, но если мы об этом можем узнать только пост-фактум, то что это нам даёт?

Зачем кому-то нужно превращать бинарь в текст, типизацию в синтаксические кастыли, если можно проще всё гонять в исходной форме?
Исходная форма — это всегда текст. Ну человеки, потому что, текст пока порождают.

Если вы о «близкой к CPU» форме — то причём тут webasm? Для этого машинные коды есть…
Если бы. Дело в том, что программирование в системе с ГЦ и без ГЦ — очень сильно разные вещи.

Идентичные.

При этом в системе с ГЦ можно программировать, как в системе без ГЦ — и это часто делается (кладём всё на массивы и «ручками» управляем из содержимым)

Нельзя. Вы просто авойдите вызовы ГЦ и не более того, все эти массивы точно так же пойдут в ГЦ.

ГЦ от управляемого хипа отличается только одним. В управляем есть new и delete, а в ГЦ есть только new. ГЦ — является обычным куском рантайма, таким же как и любой malloc. Поэтому, в языке без ГЦ вы можете заменить malloc на ГЦ и использовать только new, а вот в языке с ГЦ — нет, у вас ниоткуда delete не родиться и ГЦ не вырубится.

Много вы видели систем на C++ с ГЦ? Не на «сбоку прилепленным» C# (Java, Lisp — нужное подчеркнуть), а на С++?

К С++ прикручивается ГЦ за 5минут, только это никому не нужно. И тут говориться не об этом — говориться о рантайме. Любой рантайм с ГЦ зависит от ГЦ, а ГЦ — это такой же рантайм, который так же зависит от ГЦ, а значит он существовать не может. Таким образом ГЦ может существовать только тогда, когда он и связанный с ним рантайм не зависит от ГЦ, а значит его написать на языке с ГЦ НЕВОЗМОЖНО.

Вопрос только в том, что вы понимаете под словом «совершенное». А то пока получается тавтология: если технология А вытесняет технологию Б, то технология А — более совершенна… возможно, но если мы об этом можем узнать только пост-фактум, то что это нам даёт?

Причём тут какие-то технологии? Причём тут какое-то вытеснение? Есть реальность, в рамках которой никакого ГЦ нет, а есть уже обёртка над этой реальность — ГЦ.

Исходная форма — это всегда текст. Ну человеки, потому что, текст пока порождают.

Человеки никого не интересуют. Вы даже не поняли того, что там написано. Исходная форма для asmjs — это не текст, а это было сказано в контексте asmjs.

Если вы о «близкой к CPU» форме — то причём тут webasm?

При том, что никакого текста в природе не существует — существует бинарь и только он, а текст — это уже его представление.

Но текст никому не нужен сам по себе — текст, это представление данных в текстовой форме, что не является нативным для железяки, да и для программирования в целом. В рамках «близкой к CPU» форме числа не представляются как строки.

Для этого машинные коды есть…

Не для этого. Любая программа — это не только код, но и данные, да и сама программа — есть данные. А в рамках этих самих данных — существует некая структура.

Структуру данных «текстом» вообще никак невозможно организовать, поэтому «текстовая структура» выкидывается.

Никакого же текста попросту не существует, но его мы можем представить в бинарном формате. С этим никаких проблем нет.

К тому же, в тексте имеются некоторые интерпретируемые, т.е. текстовое представление неких отдельных объектов — те же числа. И железяка умеет в числа, и если искомое число возможно представить в железяке, то оно требует конвертации, иначе — железяка с ним работать не может. Таким образом — текстовое представление чисел — не нативно.

И такого масса, те же идентификаторы( из них код состоит на 80%+) — они так же могут иметь разное представление. И текстовые они — это так же «не нативно».

Именно поэтому бинарь и является исходной формой, исходной для машины формой. И asm — это лишь рядовой представитель. И исходная она не только для команд, исполняемых cpu, но и для данных. А код является данными.

Текст — это просто бинарный формат, который на самом деле представляет из себя поток байтов/битов. А любой поток, который ограничен форматом — является менее совершенным, нежели неограниченный, который является, по сути, множеством всех возможных форматов.

В этом и смысл совершенности, как полноты. И когда одна полнота полностью включает другую, но является несоизмеримо более полной — смысл существования другой — теряется. Она не нужна.

Именно поэтому ненужны и текстовые форматы, и тут нет места рассуждениям о «а как же читаемость человека» — они попросту несостоятельны. Причины просты:

Данные читает машина, которая не умеет в текст. Поэтому любая обработка текстовых форматов — есть to_binary | process | to_text, что попросту не имеет смысла.

И раз этот самый to_text уже существует, а значит бинарное представление является полным( оно всегда может быть полным), то это to_text можно поставить перед to_text | human_process | to_binary, таким образом — мы обеспечиваем человека текстовым форматом.

Это будет так же прозрачно, как и gzip. Очень смешно читать эти рассказы из комментов о том, «как же мне сложно будет читать tcpdump», только все эти комментаторы не знают, либо не хотят знать о том, что никакой текст по сети не гоняется — гоняется бинарь из-под gzip(подставь нужное).

Именно в этом и смысл webasm. Мы убираем AST | to_text | to_binary | browser_exec. Зачем нам это абсолютно бесполезное to_text | to_binary, к тому же — это не просто текст — это «js».

ГЦ — является обычным куском рантайма, таким же как и любой malloc.
Серьёзно? Давайте сравним.

Проект A:
1. Библиотека K использует dlmalloc.
2. Библиотека L использует tcmalloc.
3. Библиотека M вообще под ARM и несёт ещё один tcmalloc.
Ничего страшного: ну чуть нерационально будет использоваться память. Ни один аллокатор ничего о других знать, в общем, не должен.

Проект B:
1. Библиотека X написана на С# и её рантайм несёт один GC (на самом деле несколько).
2. Библиотека Y написана на Java и её рантайм несёт другой GC.
3. Библиотека Z написана на Guile — и в ней есть ещё один GC.
Что будет если мы всё это соберём вместе и запустим? В лучшем случае эти GC будут «воевать» друг с другом и тратить в три раза больше ресурсов, чем один GC. Но до этого момента ещё дожить надо. Вначале у вас будет «кровь, кишки, расчлененка», пока вы не явно не подружите ваши GC. Причём каждый из них должен знать о всех других GC, которые у вас есть.

Поэтому, в языке без ГЦ вы можете заменить malloc на ГЦ и использовать только new, а вот в языке с ГЦ — нет, у вас ниоткуда delete не родиться и ГЦ не вырубится.
Причём тут вообще язык? Языков в системе может быть сколько угодно. Вопрос в наличии/отсутствии GC в системе. То, что у вас система позволяет запускать «произвольный» язык совершенно не обозначает, что вы «поверх этого» сможете реализовать GC. В PNaCl полноценный GC был невозможен, в ASM.js — теоретически возможен, но практически — крайне проблематичен.

К С++ прикручивается ГЦ за 5минут, только это никому не нужно.
Ну да, конечно, зелен виноград, ой как зелен. Вам не кажется что ситуация, когда сотни тысяч (или даже миллионы?) проектов обходятся без GC плохо совместима с подобными заявляениямии. Вот на Java — GC почему-то нужен «прям всем». Во вкрученном «внутрь» внушительной части этих проектов Python'е — GC тоже есть. Да даже в Objective C (который почти C, только «чуть лучше») GC был… раньше. А вот в C++ «это никому не нужно». Не странно ли это?

Таким образом ГЦ может существовать только тогда, когда он и связанный с ним рантайм не зависит от ГЦ, а значит его написать на языке с ГЦ НЕВОЗМОЖНО.
Вот даже так. А кто тут песни пел про то, что ГЦ является «обычным куском рантайма, таким же как и любой malloc»? Вы уж определитесь, пожалуйста. Malloc я могу спокойно писать на языке с malloc'ом, однако.

К сожалению на этом осмысленная часть рассуждения кончается, так как последующее словоблудие расшифровке не поддаётся, так что я ограничусь, пожалуй, обсуждением GC.
Серьёзно? Давайте сравним.

Что вы хотели своим словоблудием сказать? Что опровергнуть? Что из этого следует?

Причём каждый из них должен знать о всех других GC, которые у вас есть.

Не должен. Это не из чего не следует, как из этого НИЧЕГО не следует.

Причём тут вообще язык? Языков в системе может быть сколько угодно. Вопрос в наличии/отсутствии GC в системе.

Никакого вопроса нет.

То, что у вас система позволяет запускать «произвольный» язык совершенно не обозначает, что вы «поверх этого» сможете реализовать GC.

К чему это и что это должно значить? Попытка слиться на эмуляцию? Нет, не получиться. Никому не интересно то, что «можно» запустить — всем интересно то, как это можно запустить, вернее то — что это даст. И под запустить имеется ввиду именно прямой запуск.

В PNaCl полноценный GC был невозможен, в ASM.js — теоретически возможен, но практически — крайне проблематичен.

И? Это проблемы PNaCl, а не ручного управления.

Ну да, конечно, зелен виноград, ой как зелен. Вам не кажется что ситуация, когда сотни тысяч (или даже миллионы?) проектов обходятся без GC плохо совместима с подобными заявляениямии.

Кто это должно знать и что из этого следует? Он им не нужен именно потому, что они без него жили и живут.

Вот на Java — GC почему-то нужен «прям всем».

Мир жава и мир С++ — это разные миры. Я не буду рассказывать об управляемости и производительности, но пойди там ораклу расскажите о том, что хотспот надо переписать на жаву и о том, что им нужен ГЦ.

Во вкрученном «внутрь» внушительной части этих проектов Python'е — GC тоже есть. Да даже в Objective C (который почти C, только «чуть лучше») GC был… раньше. А вот в C++ «это никому не нужно». Не странно ли это?

Нет. Сравнивать скриптуху и пускалки сишного/крестового рантайма с тем, на чём этот рантайм пишется — идиотская затея. Именно от того они и пускалки, что ни в каком ином назначении они не состоятельны.

Вот даже так. А кто тут песни пел про то, что ГЦ является «обычным куском рантайма, таким же как и любой malloc»? Вы уж определитесь, пожалуйста.

Поподробнее, где именно у меня тут противоречие? В чём мне надо определиться? Да, ГЦ обыкновенный кусок рантайма, и? Это как отменяет то, что реализация ГЦ на ГЦ рекурсивно зависит от ГЦ? Нет.

Malloc я могу спокойно писать на языке с malloc'ом, однако.

К чему это? И ГЦ можно писать на языке с ГЦ, и?

Суть в том, что языки( о которых я говорю) с маллоком никак от маллока не зависит, в отличии от языка с ГЦ. Если бы он зависел — была бы такая же рекурсивная зависимость.

Они работают с памятью напрямую и им маллок для этого не нужен. Маллок лишь некая абстракция, которая даёт и забирает куски памяти.

Язык работает в рамках системного рантайма, а там есть аллокатор. А тот в свою очередь — получает память от железяки напрямую, одним куском.

К сожалению на этом осмысленная часть рассуждения кончается, так как последующее словоблудие расшифровке не поддаётся, так что я ограничусь, пожалуй, обсуждением GC.

Слив засчитан. Кстати, что именно вы не смогли расшифровать и почему — вы ведь сможете мне показать и рассказать? А то, как я отличу «это словоблудие» от «мне нечего ответить — оправдаюсь тем, что безосновательно назову тезисы/аргументацию оппонента словоблудием»? Я должен вам поверить?

Я только совсем чуть-чуть, про GC. В С++ правит бал Rc (он же reference counting). В ObjC посмотрели на это дело и решили заменить GC на Rc, и прикрутить Arc как более простой вариант, чем умные указатели. Такой шаг со стороны Apple явно не говорит в пользу GC как парадигмы для управления памятью при системном программировании. Rc так же принят как основная парадигма памяти в Rust.

Есть и третья базовая парадигма управления памятью — MemPool. Её много в C, и немало в C++. В частности, на ней работает Apache HTTPD, очень много мелких парсеров вроде RapidJSON и специализированных библиотек вроде libtess.

Проблема GC как парадигмы в том, что она слишком универсальна. GC пытается решить абсолютно все проблемы с памятью за программиста. Это имеет свою цену. Rc и MemPool имеют довольно большой список ограничений и требуют строить архитектуру определённым образом, но в применении часто не сложнее GC. Загвоздка в том, что для Rc и MemPool нужно уметь грамотно проектировать системы. А это специфический навык, отличный от базовых навыков программирования. GC же позволяет запускать херово спроектированные системы так, чтобы они работали и не падали прямо сейчас. Пусть медленно и неэффективно, но работали.

Если человек взял такой инструмент, как С++, ему, скорее всего, нужно нечто, работающее эффективно. А это заведомо не про GC. И даже не потому, что сами реализации GC медленные, а потому, что парадигма GC не содержит в себе подсказок, как правильно спроектировать систему.

Лично я сторонник пулов памяти. Да, проектировать под них сложно. Зато это позволяет давать менее опытным разработчикам среду, которая в общем случае аналогична среде с GC по способу работы с ней, но значительно более эффективна.
UFO just landed and posted this here

Спасибо за ответы.


JVM привязана больше к инфраструктуре, а не к языку. Были причины, почему Java в своё время не заняла нишу WebAssembly, несмотря на попытки. И воз поныне там же. Подробнее можно здесь.

Да, песенка спета, да и к лучшему что так закончилось. Аплеты выкинут и целый груз с плеч.
А вобще все эти нашпигованные платформы, лезущие в интернет — изобилуют дырами. Как флеш. Может с WebAssembly такого не будет

UFO just landed and posted this here

--crate-type=cdylib — помогло от проблемы с main, спасибо. Исправил в статье.


Проблемы с rust_begin_unwind в вашем примере нет, поскольку её убирает wasm-gc. Так же, как и кучу функций из std без #![no_std]. Собирать таким образом минимальный вариант для отладки не слишком рационально. Для релизной сборки, понятное дело, оптимизатор нужен, и он проблему решит.


Теперь про стандартную библиотеку. Идея не в том, чтобы взять и что-то портировать под интерпретатор. Это как раз одни из тех граблей, которые попались Java и Flash при вытаскивании их в браузер. Нужен способ легко и просто определять свою песочницу, а внутри неё сделать набор самых базовых функций. libc это таки значительно больше, чем базовые.


На самом деле, здесь есть два различных подхода. Первый подход — сделать полностью функциональную систему на wasm-модулях. В таком случае портирование libc — хороший вариант.


Наш подход — сделать скриптовую песочницу на WebAssembly. Такую, чтобы в ней было крайне сложно прострелить себе ногу, и с настолько низким порогом входа, насколько возможно. А дизайн libc (если сравнивать, например, с CoreFoundation) добавляет свою весомую долю в базовую сложность языка. Не говоря о том, что это оверкил по функциональности.

UFO just landed and posted this here
Вы не поняли идею изначально. Не язык, а, скажем так, мета-API. С бекендом в виде wasm. И с фронтендом в виде любого языка, способного компилироваться в wasm. Для запуска специализированных модулей, скриптов, на простом интерпретаторе, без веб-окружения. Отсутствие веб-окружения сразу ломает emscrpten, который создаёт код, заточенный под веб-окружение (хотя там есть подвижки в сторону отдельных модулей).

Собственно, мнение, что это нафиг не нужно, как и нафиг не нужна архитектура wasm32-unknown-unknown в Rust уже высказано, прочитано и учтено. Сходу не найду, но в rust internals про это была не одна простыня.

Не надо забывать что webassembly появился как костыль для js.

А C++ и ObjectiveC как костыли к C. А С как костыль к B. Noted.
UFO just landed and posted this here
Если инженерия софта будет конкурсом популярности — софт будет исключительно красиво падать.
Sign up to leave a comment.

Articles