WebAssembly («wasm») похож на Native Client, но отличается, в частности, тем, что другие браузеры планируют его реализовать.
Об этом спрашивали несколько раз, так что это ошибка отслеживания.
Получаем ли мы его через cmd/compile, gccgo или llvm-go, мы можем публиковать обновления здесь.
@cherrymui и я подробно обсудили возможность порта wasm GC в
последние несколько дней:
Наш текущий вывод заключается в том, что не существует эффективного способа реализации
функциональность setjmp/longjmp в настоящее время, поэтому это не жизнеспособная цель
порта gc. Нам нужно подождать, пока он не раскрутится по-настоящему, и
поддержка обработки исключений.
Все остальные аспекты выглядели нормально, и мы даже разработали Go ABI под wasm.
(передать g и SP в стек wasm, а все остальное в эмулируемый стек Go) и
способ изменить текущий бэкэнд MIPS для поддержки wasm путем эмуляции MIPS
регистрируется как локальные переменные wasm.
Возможно, GopherJS может упростить поддержку wasm.
Из gopherjs/gopherjs#432:
Однако это не та технология, которую может использовать GopherJS. GopherJS компилируется на уровне AST, а не на уровне машинного кода.
WebAssembly можно использовать в качестве бэкенда для обычного компилятора Go.
@minux Отсутствие потоков или асинхронного ввода-вывода кажется более серьезной проблемой, чем обходные пути ABI, которые нам пришлось бы использовать из-за особенностей wasm.
@минукс , @cherrymui
не могли бы вы написать где-нибудь более подробно, что вы сделали и достигли?
как вы, возможно, знаете, сообщество go-interpreter рассматривает возможность написания интерпретатора на основе байт-кода LLVM или wasm.
(у нас может даже быть студент GSoC, работающий над интерпретатором байт-кода wasm [1] , так что только часть «потребления байт-кода», а не «производство байт-кода с помощью некоторой цепочки инструментов на основе Go»)
было бы здорово свести к минимуму количество дублированных усилий и несоответствие импеданса между различными компонентами.
Я настоятельно рекомендую это как стратегическую функцию. Учтите, что всего через несколько лет веб-программисты будут стекаться толпами, чтобы выбрать свой язык для компиляции в веб-сборку. Чем раньше мы присоединимся к гонке, тем лучше. Mozilla активно продвигает Rust в качестве предпочтительного языка веб-ассемблера...
Я согласен с тем, что сказал @RaananHadar . Было бы жаль, если бы спецификация не соответствовала потребностям Go, особенно с учетом уникальности среды выполнения Go.
РЕДАКТИРОВАТЬ: Приносим извинения за характер этого комментария MeToo :) Спасибо за указатель, Брэд.
Напоминание: https://golang.org/wiki/NoMeToo
Контекст стековой машины WebAssembly состоит из линейной памяти и стека операций. IIUC, сохранение контекста виртуальной машины может быть выполнено путем сохранения:
В глобальный список сохраненных контекстов в структуре контекста виртуальной машины, если таковые имеются.
Таким образом, setjump должен просто восстановить эти значения и продолжить цикл интерпретатора, как обычно (это похоже на то, как виртуальная машина байт-кода emacs реализует сигналы: https://github.com/emacs-mirror/emacs/blob/master/src /bytecode.c#L785). Поверх этого можно реализовать систему исключений, хотя я не уверен, насколько это будет эффективно.
Кроме того, в спецификации webassembly упоминается, что высота стека в любой момент байт-кода известна статически , что делает все операции со стеком эквивалентными операциям с регистрами, уникальными для каждой позиции в стеке. В этой статье описывается способ достижения такого сопоставления стека -> регистра для преобразования машинного кода стека в собственный код, что позволяет нам использовать setjmp/longjmp как обычно.
Изменить: как насчет использования panic()
и recover()
со специальными значениями WasmException{}
для сигнализации об исключении? recover
уже выполняет тяжелую работу по раскручиванию стека, восстановить цикл интерпретатора после восстановления после перехваченного исключения не составит труда.
Да, в основном дискуссия с @cherrymui привела к аналогичным выводам.
Первоначальный дизайн с @cherrymui таков :
(этот этап сосредоточен на том, чтобы заставить $GOROOT/test/sieve.go работать, асинхронный ввод-вывод не
обдуманный.)
мы повторно используем порт MIPS, отображая 31 регистр MIPS как локальный WASM
переменные и использовать только стек WASM
для промежуточных результатов. Мы не можем использовать механизм вызова функций WASM для
большинство функций Go, потому что
отсутствие поддержки раскручивания стека.
изменить objlink mips (cmd/internal/obj) для эмуляции каждой инструкции MIPS
с соответствующими инструкциями WASM.
Это делает реализацию setjmp/longjmp (он же runtime.gogo) тривиальной и
повторно использует много существующих усилий.
Go уже должен реализовать свой собственный стек, отдельный от стека WASM.
потому что Go нужно копировать
стек, карты указателей стека и поддержка раскручивания стека, которые не
можно получить в WASM.
(Эта стратегия также согласуется с портом LLVM, мы не можем использовать стек LLVM для
почти те же причины
(если только мы не добавим собственный внутренний проход в LLVM для кодирования указателя стека
карты))
Вероятно, нам потребуется использовать большой переключатель для потоков непрямых переходов? Это
аналогично подходу NestedVM.
http://nestedvm.ibex.org/
Если мы решим реализовать нативный бэкенд WASM, то можем сделать так:
Go ABI это:
все параметры (включая результаты) на (эмулированном) стеке Go,
при входе в функцию в стеке WASM находятся:
эмулированный SP, g.
Обсуждение происходило больше месяца назад, и я, вероятно, забыл некоторые
подробности на данный момент.
IIUC, вы можете полностью отказаться от стека WASM (согласно спецификации). Расширяемый и копируемый стек go все еще нуждается в изучении.
Да, первоначальный проект, о котором я упоминал, использует стек WASM только для
промежуточные продукты, используемые в вычислениях. Все данные находятся либо в куче Go (линейные
memory) или псевдорегистры в локальных переменных WASM.
Я не ожидаю, что спецификация WASM будет включать перемещение/сегментирование и копирование стека.
Он редко используется основными языками, на которые нацелен WASM.
@bradfitz @minux @vibhavp Каково текущее состояние wasm в golang? С 13 марта ничего не произошло! можно ли будет преобразовать golang в wasm в будущем? может быть, есть какая-нибудь карта маршрута этого?
если кто-то решит внедрить поддержку wasm, могу предложить свое время для неглобальных задач
@SerkanSipahi , над этим никто не работает. Эта ошибка помечена как LongTerm. Если что-то начнет происходить, вы увидите обновления здесь.
Хорошая дорожная карта?
У нас есть DELVE и GDLV для отладки golang с графическим интерфейсом. Он также хорошо работает на всех настольных компьютерах, и производительность превосходна.
https://github.com/derekparker/дельве
https://github.com/aarzilli/gdlv
Теперь GDLV основан на NUCULAR, который блестит некоторыми приятными абстракциями.
https://github.com/aarzilli/nucular
Итак, я подумал, что это будет хорошей основой для того, что уже было сделано здесь:
Теперь также есть 5 библиотек WASM go:
https://github.com/search?l=Go&q=webassembly&ref=simplesearch&type=Repositories&utf8=%E2%9C%93
NaCl отключен - https://blog.chromium.org/2017/05/goodbye-pnacl-hello-webassembly.html
Так что это, вероятно, следует очистить - https://github.com/golang/go/tree/master/misc/nacl
Я считаю, что NaCl используется различными частями экосистемы Go. То есть он используется не только Chrome. И в любом случае это объявление в блоге посвящено PNaCl, который, хотя и обеспечивает функциональность, аналогичную NaCl, на самом деле является совершенно другим продуктом, основанным на другой технологии. Поэтому удаление поддержки NaCl из Go в настоящее время преждевременно.
В любом случае, удалим мы NaCl из Go или нет, не имеет ничего общего с тем, добавим ли мы поддержку Web Assembly.
Я бы сказал, что PNaCl - это просто расширение над NaCl для предоставления независимого от платформы кода https://developer.chrome.com/native-client/nacl-and-pnacl . Я спросил об устаревании NaCl здесь - https://groups.google. com/d/topic/native-client-discuss/wgN2ketXybQ/обсуждение
Можно ли получить список различных частей экосистемы Go, где до сих пор используется NaCl?
Если вы пройдете их по одному, переход на WebAssembly станет более интересным.
Я бы сказал, что PNaCl — это просто надстройка над NaCl.
Вы можете говорить что угодно, но это не значит, что вы правы. Это совершенно разные ISA, NaCL — это просто целевая ISA (x86/arm) с некоторыми ограничениями, а PNaCl — это совершенно другая ISA для абстрактной машины.
Go никогда не поддерживал PNaCL, и в любом случае порт Go NaCL никогда не подходил для Chrome. Это не имело ничего общего с Chrome, его нельзя было использовать в браузере. Откажется ли Chrome от NaCL или от PNaCL, не имеет никакого отношения к Go. Нада, ноль, не актуально . Сколько еще раз это надо говорить? Конечно, если NaCL будет полностью заброшен, то Go в какой-то момент тоже будет вынужден отказаться от него.
Поддержка WebAssembly в Go не имеет абсолютно никакого отношения к NaCL. Go может получить или не получить поддержку WebAssembly. Если или когда он может получить такую поддержку, это не имеет отношения к состоянию порта NaCL.
Вот очень важная часть экосистемы, где мы используем nacl: https://play.golang.org/p/MfJIq8wb5-
(который работает на стороне сервера, а не nacl-в-браузере)
Откажется ли Chrome от NaCL или от PNaCL, не имеет никакого отношения к Go. Нада, ноль, не актуально.
А кто тогда будет поддерживать загрузчик песочницы и тулчейн? Он импортирован из проекта Chrome, который переключил усилия на WebAssembly. Не было бы разумно проследить и посмотреть, можно ли уже перенести игровую площадку Go из песочницы NaCl в песочницу WebAssembly? Его также можно запустить на стороне сервера.
Я думаю, что все выступают за поддержку WebAssembly.
Время обсудить отказ от NaCl наступит после того, как WebAssembly полностью заработает. Нет смысла обсуждать это раньше.
@ianlancetaylor , можете ли вы уточнить «после того, как WebAssembly полностью заработает»?
На первый взгляд кажется, что webassembly.org говорит, что «первоначальная версия WebAssembly достигла межбраузерного консенсуса», и wasm доступен в текущих или будущих версиях браузеров от всех поставщиков браузеров .
@ vine77 Я имею в виду, что после того, как WebAssembly полностью заработает для программ Go, по крайней мере, так же хорошо, как сегодня работает NaCl.
Итак, какой следующий тест должен пройти, чтобы WebAssembly работал с программами Go?
@techtonik Я чувствую, что здесь есть некоторая путаница. Когда мы говорим, что WebAssembly должен работать с программами Go, мы имеем в виду, что компилятор Go должен генерировать код WebAssembly, который может выполняться в браузере. Мы имеем в виду, что вы должны быть в состоянии написать что-то вроде GOOS=wasm go build hello.go
и получить программу, которая может работать в браузере. Мы даже отдаленно не близки к этому. Мы даже не начали. Так что нет никакого "следующего теста". Предстоит много работы. И, насколько я знаю, никто этим активно не занимается.
@ianlancetaylor
Для golang существует 4 реализации. Один серьезно впечатляет. См. мой предыдущий комментарий для ссылок.
Мальчик, эта тема похожа на машину Chevy Chase, которую видели с детьми на заднем сиденье, кричащими "мы еще не там" :)
@ joeblew99 joeblew99 : ни одна из этих ссылок не может скомпилировать Go to WebAssembly.
Это такие вещи, как компилятор WebAssembly -> amd64, написанный на Go.
Я боялся, что ты это скажешь. Справедливо.
Так что же нужно для "воспитания"? Так все знают...
Gopherjs допустил ту же ошибку, не находясь на правильном уровне в архитектуре цепочки инструментов компилятора/генерации кода?
Там длинный список. Большинство из них так или иначе связано со сборкой мусора.
Это, наверное, не полный список.
Когда мы говорим, что WebAssembly должен работать с программами Go, мы имеем в виду, что компилятор Go должен генерировать код WebAssembly, который может выполняться в браузере.
@ianlancetaylor , не будет ли проще сначала настроить таргетинг на не-веб-сайты? NaCl также изначально был разработан для запуска в браузере, но затем получил независимый от браузера загрузчик, который в настоящее время использует Go. WebAseembly без браузера - http://webassembly.org/docs/non-web/ - и это говорит о минимальных оболочках для тестирования.
@ randall77 можно ли извлечь из этого списка действенный контрольный список? Нравится основной выпуск со ссылками на выпуски, в которых подробно исследуется каждый аспект?
@techtonik по отношению к не-сети: @vibhavp работает над этим в контексте стажировки GSoC, о которой я упоминал в нескольких сообщениях выше.
это там: https://github.com/go-interpreter/wagon
@techtonik : я думаю, что подходящим местом для такого контрольного списка является документ с предложением о поддержке wasm. Как только такое предложение будет принято и/или люди будут активно над ним работать, они, конечно же, смогут использовать вопросы для отдельных задач. На данный момент это преждевременно - я не знаю, чтобы кто-то активно работал над (предложением или кодом).
Я согласен с предложением док.
Все, что я делаю / противоречия, находятся в этой теме, и их просто нужно объединить вместе с дорожной картой, которая позволяет поэтапно балансировать риск / вознаграждение.
Я также хотел бы, чтобы он обращался и к графике, поскольку она торчит для меня как больной палец.
Я автор GopherJS , компилятора с Go на JavaScript. Я написал этот проект, потому что твердо верю, что должны быть альтернативы использованию JavaScript в браузере, такие альтернативы, как Go и другие. У меня есть приличные знания о компиляторах, SSA, машинной архитектуре и т.д., но я, вероятно, упускаю много деталей, так как я еще не написал бэкэнд компилятора для машинного кода. Вот почему я не чувствую себя квалифицированным, чтобы написать полный документ с предложением. Тем не менее, я хотел бы получить критический отзыв о моих мыслях о Go и WebAssembly.
Когда я смотрю на WebAssembly, мне кажется, что он сильно отличается от обычных целей машинного кода, таких как x86 или arm. Например, его архитектура представляет собой стековую машину, а не регистровую машину. Это означает, что он не подходит сразу как просто еще одна цель на последнем этапе компилятора Go рядом с x86 и друзьями. Одно из решений может состоять в том, чтобы не размещать его там, а вместо этого использовать совершенно другой подход к созданию WebAssembly. Код для этого подхода должен был бы жить помимо существующих стадий компиляции, что было бы совсем нехорошо. В этом сценарии можно даже рассмотреть форк компилятора. Короче: я не вижу, чтобы это происходило.
Может быть альтернатива: эмулировать то, что нам нужно. Мы можем использовать стековую машину для эмуляции регистровой машины и, надеюсь, сделать это с достаточной производительностью. WebAssembly имеет линейную память с инструкциями по загрузке и сохранению, и это хорошо. Мы бы вообще не использовали инструкцию WebAssembly call
и вместо этого развернули бы собственный механизм управления стеком и вызова. Стеки будут жить в этой линейной памяти и управляться средой выполнения Go. Stackpointer будет глобальной переменной. Весь код будет жить в одной функции WebAssembly. Верхний уровень будет гигантским оператором switch (или эквивалентом WebAssembly на основе br_table
) с одной ветвью для каждой функции. Каждая функция будет иметь другой оператор switch с одной ветвью на базовый блок SSA. Есть некоторые детали, которые я здесь опускаю, но в целом это выглядит как приличная регистрационная машина. Конечно, производительность сильно зависит от того, насколько хорошо WebAssembly может преобразовать эти конструкции в реальный машинный код.
Так что, пожалуйста, скажите мне: я совсем наивен и сумасшедший? Тогда я счастлив отложить свои мысли, пока я не узнаю больше. Если нет, то это может послужить отправной точкой для какого-то фактического документа с предложением. Спасибо.
В дополнение ко всей работе, необходимой на стороне Go, есть некоторые вещи, которые могут потребоваться WebAssembly, прежде чем среда выполнения Go сможет нацелить ее.
В WebAssembly пока нет потоков, но они есть в дорожной карте и есть спецификация. https://github.com/WebAssembly/потоки
Что касается сбора мусора, похоже, что в будущем может быть несколько вариантов, основываясь на выступлении Лин Кларк https://youtu.be/HktWin_LPf4?t=28m31s .
28:31
Итак, сегодня вы можете отправить свой собственный сборщик мусора с кодом, если хотите, но
медленно по нескольким причинам, и группа сообщества делает возможным код WebAssembly
для использования только со встроенным GC, который является высокооптимизированным, что браузеры
работали, поэтому он будет работать быстро, и у вас будет эта интеграция.
Как и в случае с гомобилем, здесь нужно разобраться с языковым мостом.
@ randall77 также упомянул потоки как требование для GC. Это действительно жесткое требование для первой версии? Параллелизм также может быть выполнен в одном потоке.
Что касается реализации GC, мое личное мнение таково, что я не верю в то, что один GC будет управлять ими всеми. Я бы предпочел, чтобы у Go был сборщик мусора, специфичный для Go, а у Python — сборщик мусора, специфичный для Python. Насколько я сейчас понимаю, полностью управляя нашей собственной кучей и стеками в линейной памяти WebAssembly, мы должны иметь возможность использовать GC, который уже есть в Go.
@neelance Да, несколько реальных потоков WebAssembly - это хорошо, а не строгое требование.
Предложение GC для WebAssembly все еще находится в стадии разработки. Желающие могут принять участие здесь:
@neelance , я ничего не знаю о компиляторах, SSA, архитектуре машины и т. д. Не могли бы вы рассказать, как то, что вы описали, повлияет на размер двоичного файла? Если я правильно понимаю, эффективность размера была одной из главных целей WebAssembly . Это должно быть одним из приоритетов и для этого компилятора Go->WebAssembly, верно?
@alxkchr Мой опыт показывает, что повторение из-за шаблонного кода генерации кода можно значительно компенсировать, применив gzip. Тем не менее, мое предложение не является самым эффективным решением с точки зрения размера двоичного файла. Тем не менее, какое -то решение, которое можно реализовать за разумное время, лучше, чем отсутствие решения, верно? ;-) Также лично для меня размер двоичного файла не является одним из первых приоритетов.
к вашему сведению: я начал реализовывать это.
@neelance лучшая новость :) ты следишь за спецификацией? (надеюсь)
Спецификация Go? Это новый бэкенд/цель для обычного компилятора Go, так что спецификация уже там. ;)
я имею в виду спецификацию wasm :)
@неланс
к вашему сведению: я начал реализовывать это.
Не могли бы вы поделиться, какой подход будет использоваться для решения
Наш текущий вывод заключается в том, что не существует эффективного способа реализации
функциональность setjmp/longjmp в настоящее время, поэтому это не жизнеспособная цель
порта gc. Нам нужно подождать, пока он не раскрутится по-настоящему, и
поддержка обработки исключений.
(https://github.com/golang/go/issues/18892#issuecomment-276858667)
@neelance : я знаю, что еще рано, но я думаю, что было бы разумнее назвать wasm GOARCH wasm32
(то же самое для пакетов)
@sbinet Стоит учитывать, что архитектуры/пакеты ARM называются arm
и arm64
(аналогично mips
и mips64
), а не arm32
и arm64
. Однако я не знаю, следует ли считать это хорошим или плохим примером.
@SerkanSipahi Изначально я ориентируюсь на V8 (nodejs/chrome) и использую https://webassembly.github.io/spec/ в качестве документации о том, что делать.
@ stuart-warren Да, мой WIP находится в этой ветке. Тем не менее, пока не пытайтесь использовать его, его не так-то просто построить прямо сейчас, и он полон скопированного кода и заглушек/хаков. Я объявлю об этом здесь, когда он достигнет некоторого альфа-состояния.
@cznic Как написано выше, я вообще не использую инструкцию wasm call
, я управляю своим собственным стеком в линейной памяти. Таким образом, setjmp/longjmp может быть реализован.
@sbinet На самом деле это будет 64-битная архитектура, поскольку wasm выполняет 64-битные операции.
@neelance не совсем. Спецификация WebAssembly на данный момент поддерживает только 32-битные адресные пространства, спецификация wasm64
планируется позже .
Интересно, спасибо за ссылку. Возможно, мы захотим вернуться к этому позже. В настоящее время я храню все в 64-битных переменных, поэтому int
, uint
и uintptr
имеют размер 64 бита. Однако для адресации памяти используются только первые 32 бита. Это легче реализовать на первых порах.
Тогда это звучит как wasm64p32 (следуя названию nacl) или что-то в этом роде.
аналогичный.
4 ноября 2017 г., 5:28, «Ричард Мусиол» [email protected] написал:
Интересно, спасибо за ссылку. Возможно, мы захотим вернуться к этому позже.
В настоящее время я храню все в 64-битных переменных, поэтому int, uint и uintptr
все имеют размер 64 бита. Однако только первые 32 бита используются для
адресация памяти. Сначала это легче реализовать.—
Вы получаете это, потому что подписаны на эту тему.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/golang/go/issues/18892#issuecomment-341889653 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAgwpPTbfHRmoYNXLQfcPMVnARxb0UGrks5szEpjgaJpZM4L0o7D
.
Тогда это звучит как wasm64p32 (следуя названию nacl) или что-то в этом роде.
аналогичный.
Я не думаю, что есть смысл иметь два номера, потому что архитектура будет только одна (с выбором размера адресного пространства). С сайта webassembly.org :
wasm32 и wasm64 — это просто режимы WebAssembly, которые выбираются с помощью флага в заголовке модуля и не подразумевают каких-либо семантических различий, кроме того, как обрабатывается линейная память.
Я не думаю, что есть смысл иметь два номера, потому что архитектура будет только одна (с выбором размера адресного пространства). С сайта webassembly.org:
wasm32 и wasm64 — это просто режимы WebAssembly, которые выбираются с помощью флага в заголовке модуля и не подразумевают каких-либо семантических различий, кроме того, как обрабатывается линейная память.
Это амбициозное заявление. Это может оказаться правдой, но WebAssembly CG/WG не изучила wasm64 в достаточной степени, чтобы я мог быть уверен, что это утверждение верно.
Давайте позволим @neelance работать. Имена легко изменить позже.
Я знаю, что Go компилируется непосредственно в машинные инструкции (AFAIK), но мне интересно, компилировал ли кто-нибудь Go в C. Было бы интересно попробовать Go --> C --> wasm (хотя и не очень эффективно).
@TomerHeber это возможно в виде перевода на C++, а не компиляции, но, вероятно, это будет больше работы, чем компиляция в сам wasm
Всем привет. Вот обновленная информация о моей работе: я делаю очень хорошие успехи, во многом благодаря отличной работе команды Go и участников. Большая часть кода является общей для разных архитектур/платформ, поэтому не так много, как я ожидал, нужно было реализовать.
Вот список некоторых вещей, которые уже работают нормально:
bytes, container/heap, container/list, container/ring, encoding/ascii85, encoding/asn1, encoding/base32, encoding/binary, encoding/csv, encoding/hex, errors, flag, hash/adler32, hash/crc32, hash/crc64, hash/fnv, html, image, image/color, index/suffixarray, math, math/bits, path, sort, strconv, strings, text/scanner, text/tabwriter, unicode, unicode/utf8, unicode/utf16
Некоторые вещи, над которыми еще нужно поработать:
Я очень доволен прогрессом за полтора месяца, и то только в свободное время. Я думаю, есть хороший шанс, что мы сможем включить это в Go 1.11. Ожидайте моего следующего обновления в январе, так как я буду в отпуске, а потом будут праздники.
Можно ли распараллелить некоторые из этих задач? Некоторые биты кажутся интересными для праздников.
Не стесняйтесь изучить это и создать PR на моей вилке. Вы также можете найти меня на Gophers Slack.
Одной из областей исследования может быть оптимизация использования стека. Сейчас на этапе выделения регистров регистры (локальные переменные в wasm) выделяются для каждой операции. get_local
и set_local
всегда используются до и после каждой операции. В этом нет необходимости, если значение может просто остаться в стеке для использования какой-либо последующей операцией. Я предлагаю добавить псевдорегистр REG_STACK
и заставить генератор команд пропускать get_local
и set_local
, если этот регистр используется. Затем заставьте regalloc
использовать этот регистр, когда это необходимо.
Ре:
хороший слой взаимодействия JS
Есть ли разумный способ реализовать это для wasm в настоящее время? Я думал, что взаимодействие Dom/js было выходом с wasm. Если это возможно, это было бы огромно!
Вы можете импортировать и экспортировать функции, которые могут иметь аргументы float64
и int32
, и у вас есть общая линейная память. Все остальное можно построить вокруг этого. Только сборка мусора была бы не так хороша.
(Я пытался опубликовать это в вашем репозитории (@neelance), но я не мог понять, как публиковать проблемы...)
можно ли использовать набор инструментов wabt
вместо вызова/импорта js.foo
?
Мне было проще взаимодействовать с wabt
вместо полной установки nodejs
:)
(Я также пытаюсь интерпретировать простую программу main.go
, переведенную в a.wasm
здесь: go-interpreter/wagon#36...)
Я включил задачи на своем форке, не стесняйтесь публиковать там.
Я не очень понимаю ваш вопрос. Вы говорите о wasm-interp
? Что-то должно скомпилировать и запустить байт-код wasm, и вам нужна среда JS для взаимодействия с остальной частью системы, например, для вывода на консоль.
Кстати: вы видели https://github.com/neelance/go/tree/wasm-wip/misc/wasm?
Это здорово. Для желающих попробовать свои силы в компиляции и выполнении Go to wasm -
GOOS=js GOARCH=wasm ./bin/go build -o out.wasm wasm.go
./misc/wasm/go_js_wasm_exec out.wasm
Наслаждаться !
Если вы свяжете go_js_wasm_exec
своим PATH, вы даже сможете использовать go run
. ;-)
Привет, ребята, как обстоят дела со сборкой мусора в Go for WASM? Мы начали говорить о переносе Crystal , и похоже, что у Crystal, вероятно, те же проблемы, что и у Go в настоящее время с GC. Можем ли мы каким-либо образом сотрудничать или помочь рабочей группе WebAssembly в этой ситуации?
Пожалуйста, не стесняйтесь присоединиться к упомянутой выше ветке или дайте нам знать, где мы могли бы пообщаться /, возможно, сотрудничать по этому вопросу.
Возможно, путь Opal на данный момент является более разумным подходом, пока WASM не созреет в этой области, но было бы хорошо знать это наверняка, прежде чем идти по этому пути.
Привет, ребята, я хотел поделиться тем, над чем я работал последние несколько месяцев, так как я думаю, что большая часть базового кода актуальна: https://github.com/matthewmueller/joy
Сейчас я ориентируюсь на JS (ES3), но компилятор реализует граф зависимостей для всех объявлений (функции, переменные и т. д.). Затем он сортирует граф и переводит только те объявления, которые используются в программе.
Я не думаю, что было бы слишком сложно использовать этот график и ориентироваться на WebAssembly. Я готов помочь и сотрудничать в любом случае, что я могу.
Для получения дополнительной информации вот несколько соответствующих ссылок:
Что касается вышеприведенной проблемы GC для Crystal, она также может применяться для Go, обратите внимание на замечания @kripken и следующее обсуждение здесь: https://github.com/WebAssembly/binaryen/issues/1312#issuecomment -348409211
Потенциально мы захотим обновить https://github.com/AppCypher/webassemblylanguages?
Я надеюсь, что у всех были хорошие каникулы. Вот обещанное обновление:
Со времени моего последнего обновления мне удалось настроить и запустить отражение, увеличение стека и сборку мусора. Дополнительные доработки дошли до того, что сейчас проходят тесты 104 из 136 пакетов stdlib. Кроме того, многие тесты компилятора зеленые. Хороший прогресс!
Пожалуйста, имейте в виду, что в настоящее время я сосредоточен на поддержке и правильности функций. Я еще не делал никаких оптимизаций для производительности или размера вывода.
Я приветствую эксперимент (и @neelance так много для GopherJS для превосходных goroutines по сравнению с Promise
, вы, вероятно, спасли меня от C++ !), поэтому следующее просто попытка добавить потенциально полезную информацию и возможно, даже, возможно, чтобы привлечь внимание к несоответствию между Go и целью WASM. Также потенциально может прояснить проблему для некоторых читателей. Кроме того, потому что я хотел найти подходящее место для сброса следующей цитаты @rossberg , которую я нашел, когда самостоятельно думал о том, как скомпилировать что-то вроде горунтина в WASM.
@neelance ответил :
@cznic ответил :
@neelance написал :
Мы бы вообще не использовали инструкцию WebAssembly
call
и вместо этого развернули бы собственный механизм управления стеком и вызовов. Стеки будут жить в этой линейной памяти и управляться средой выполнения Go. Stackpointer будет глобальной переменной. Весь код будет жить в одной функции WebAssembly. Верхним уровнем будет гигантский оператор switch (или эквивалент WebAssembly на основеbr_table
) с одной ветвью для каждой функции. Каждая функция будет иметь другой оператор switch с одной ветвью на базовый блок SSA.Не могли бы вы поделиться, какой подход будет использоваться для решения:
@minux писал :
Наш текущий вывод заключается в том, что не существует эффективного способа реализации
функциональность setjmp/longjmp в настоящее время, поэтому это не жизнеспособная цель
порта gc. Нам нужно подождать, пока он не раскрутится по-настоящему, и
поддержка обработки исключений.@cznic Как написано выше, я вообще не использую инструкцию wasm
call
, я управляю своим собственным стеком в линейной памяти. Таким образом, setjmp/longjmp может быть реализован.
По словам «со-дизайнера» и «автора спецификации» WASM, ограничения на call
, которые делают его неподходящим для Go, имеют какое-то отношение к безопасности/безопасности:
@rossberg писал :
Вы не можете легко «заменить» стек вызовов, так как нет возможности подтвердить адреса возврата (*). Однако при необходимости вы можете реализовать теневой стек для ваших локальных переменных в линейной памяти.
На самом деле WebAssembly в настоящее время вообще не раскрывает понятие встроенного «стека». Как и ряд других дизайнерских решений, это важно: поскольку Wasm работает в Интернете, он должен быть «безопасным». Вот почему она типизирована, не имеет неопределенного поведения, код отделен от памяти (и не адресуется), проверяются приведения к типам функций и т. д. Наличие явного понятия функции также обеспечивает другие преимущества, такие как эффективное распределение регистров, параллельное или ленивое выполнение. компиляция, полезные инструменты отладки и т. д.
Поток управления действительно частично структурирован: ветки на самом деле являются только разрывами и продолжениями, так что вы не можете создать непреодолимый поток управления. Это тоже особенность.
[…]
(*) Предположительно, вы могли бы эмулировать явные адреса возврата с индексами в гигантский переход по таблице, скомпилировав всю вашу программу в единую циклическую функцию. Но это, вероятно, было бы довольно медленным и разрушило бы большую часть экосистемы WebAssembly .
Таким образом, производительность и совместимость с экосистемой WASM того, что пытается сделать @neelance, вероятно, будут неоптимальными?
Ссылаясь на умение @neelance оптимизировать производительность GopherJS .
Я не знаю, что вы подразумеваете под «совместимостью с экосистемой WASM», поэтому я не могу это комментировать. По поводу производительности могу сказать следующее:
Да, текущий подход — не самый оптимальный способ выразить поток управления в WebAssembly, но сегодня он работает. Возможно, в будущем можно будет больше использовать инструкцию WebAssembly call
, но для этого WebAssembly потребуется добавить еще несколько функций, и потребуется гораздо больше работы на стороне Go, чтобы быть совместимым с этим. Я бы предпочел иметь что-то с 80% производительностью, которое действительно работает, чем что-то со 100%, но только гипотетическое. ;-)
Если вас интересуют дополнительные технические подробности, свяжитесь со мной на #webassembly по адресу https://invite.slack.golangbridge.org/.
Я не знаю, что вы подразумеваете под «совместимостью с экосистемой WASM», поэтому я не могу это комментировать.
Возможно, @rossberg имеет в виду _"победить большую часть экосистемы WebAssembly"_, это совместимость с инструментами и другими языками в экосистеме, которые не обходят стороной call
и защищенный стек вызовов, по существу эмулируя ваш собственные продолжения, использующие таблицы switch
?
но для этого WebAssembly нужно было бы добавить еще несколько функций
Я надеюсь, что WASM лучше приспосабливается к языкам с горутинами (зелеными потоками), потому что они бесспорно превосходят модель раскручивания стека JavaScript Promise
.
Я бы предпочел иметь что-то с 80% производительностью, которое действительно работает, чем что-то со 100%, но только гипотетическое. ;-)
О, я полностью согласен, поэтому я позаботился о том, чтобы предварить свой предыдущий пост аплодисментами за ваши плодотворные усилия.
Чем популярнее в сети/WASM мы сможем сделать Go или другие языки с зелеными потоками, тем больше у нас шансов получить лучшие примитивы WASM (например, аналогичные gcc -fsplit-stack
?) для повышения производительности в конечном итоге. .
Если ваша реализация действительно достигнет 80% оптимальной производительности в рамках текущих ограничений WASM, я буду приятно удивлен. Если результат производительности слишком низкий, это может ограничить демонстрацию популярности зеленых потоков по сравнению с моделью, основанной на обратном вызове JavaScript Promise
(потенциал иронии «победить большую часть экосистемы WebAssembly», если мы предполагаем, что это дизайн был обусловлен приоритетом оптимизации JavaScript :-).
Также обратите внимание, что я обдумываю (пока нет твердого решения) добавить дженерики класса типов в Go в качестве транспилятора (и предоставляю свой анализ предложения дженериков для Go 2), так что я также потенциально участвую в том, чтобы внести свой вклад, чтобы попытаться увеличить популярность.
@ shelby3 Пожалуйста, прекратите использовать форматирование, которое делает ваш текст настолько мелким, что его невозможно прочитать. Если вы считаете, что что-то не стоит того, чтобы люди читали, не пишите это в первую очередь. Делая его нечитаемым, не давая намека на то, что скрыто, читатели тратят вдвое (или больше) времени, пытаясь его расшифровать. Я думаю, что это противоречит вашему первоначальному намерению.
@ shelby3 Я отредактировал ваши сообщения, чтобы отказаться от форматирования мелкого текста. Пожалуйста, прекрати это делать.
Изменение https://golang.org/cl/102835 упоминает эту проблему: go/build, cmd/dist: add js/wasm architecture
Изменение https://golang.org/cl/103255 упоминает эту проблему: wasm: add scripts for running WebAssembly binaries
Изменение https://golang.org/cl/103256 упоминает эту проблему: cmd/compile: add SSA config options noAvg and noHmul
Изменение https://golang.org/cl/103275 упоминает эту проблему: cmd/compile/internal/gc: factor out beginning of SSAGenState.Call
Изменение https://golang.org/cl/103295 упоминает эту проблему: cmd/compile: add wasm architecture
Изменение https://golang.org/cl/103535 упоминает эту проблему: cmd/compile: wasm stack optimization
Изменение https://golang.org/cl/103795 упоминает эту проблему: cmd/link: add wasm architecture
Изменение https://golang.org/cl/103877 упоминает эту проблему: runtime: add js/wasm architecture
Изменение https://golang.org/cl/103915 упоминает эту проблему: internal/bytealg: add wasm architecture
Хорошо, похоже, что многие CL начинают пролетать мимо.
Как у нас дела с политикой переноса: https://github.com/golang/go/wiki/PortingPolicy ?
В частности, как будут выглядеть строители?
Я предполагаю, @neelance , что вы подписываетесь на поддержку порта?
(Мои извинения, если один из CL все это разъясняет, я не читал их все.)
Да, я буду поддерживать порт. @bradfitz в настоящее время изучает возможность настройки конструктора.
Изменение https://golang.org/cl/106995 упоминает эту проблему: sync/atomic: add wasm architecture
Изменение https://golang.org/cl/106996 упоминает эту проблему: math: add wasm architecture
Изменение https://golang.org/cl/106997 упоминает эту проблему: time: add wasm architecture
Изменение https://golang.org/cl/106998 упоминает эту проблему: mime: add wasm architecture
Изменение https://golang.org/cl/109195 упоминает эту проблему: syscall/js: add package
Изменение https://golang.org/cl/109976 упоминает эту проблему: syscall: enable some nacl code to be shared with js/wasm
Изменение https://golang.org/cl/109977 упоминает эту проблему: os: add js/wasm architecture
Изменение https://golang.org/cl/109995 упоминает эту проблему: net: add js/wasm architecture
Изменение https://golang.org/cl/110095 упоминает эту проблему: crypto: add js/wasm architecture
Изменение https://golang.org/cl/110096 упоминает эту проблему: all: skip unsupported tests for js/wasm
Изменение https://golang.org/cl/112736 упоминает эту проблему: env/js-wasm, dashboard: add start of a js-wasm builder
Изменение https://golang.org/cl/113515 упоминает эту проблему: misc/wasm: make wasm_exec.js more flexible
После прочтения архитектуры веб-сборки для документа Go , особенно для реализации системного вызова JavaScript, построенной на модуле Node 'fs' и практически не реализованной для браузерной стороны, я задаюсь вопросом, можем ли мы или хотели бы попытаться реализовать их с помощью _новые_ API браузера? В частности, похоже, что спецификация FileSystem API может поддерживать по крайней мере некоторые системные вызовы. (FileSystem по-прежнему является проектом редактора и реализована только в FireFox, Chrome и Opera. Кроме того, к последним двум она имеет префикс «webkit-».)
Я мог бы попытаться сделать доказательство концепции, если вы считаете, что это может быть достойным подходом.
Изменение https://golang.org/cl/114197 упоминает эту проблему: runtime, sycall/js: add support for callbacks from JavaScript
Привет всем, мне нравится работа, проделанная @neelance , и мне было интересно, можно ли будет с этой реализацией WASM (скажем, ее первым выпуском) также использовать cgo
. Встроить код C, скомпилировать в GO, скомпилировать в WASM. Это была бы чертова суперспособность. Вы все делаете потрясающую работу. Потрясающий.
@cmaster11 Рад слышать, что вам это нравится. :) На ваш вопрос: cgo
не компилирует C to Go, вместо этого он компилирует оба языка в машинный код с помощью соответствующих компиляторов, а затем объединяет результаты в один двоичный файл. Вы уже можете использовать emscripten для компиляции кода C в WebAssembly. Теоретически должна быть возможность загрузить оба двоичных файла WebAssembly во время выполнения и заставить их взаимодействовать. Однако я думаю, что маловероятно, что проект Go потратит время на облегчение этого варианта использования в ближайшем будущем.
видимо в основном миллениалы
@ shelby3 Я, наверное, старше тебя, и я проголосовал за тебя. Проблема здесь просто в вашей неспособности общаться.
Это не вопрос власти. @andybons сделал вам одолжение, отредактировав ваш пост, чтобы его могли прочитать другие.
Поддержка js/wasm без webidl означает, что мы не можем много взаимодействовать с другими языками из веб-браузера. В архитектуре wasm, похоже, ничего не упоминалось о webidl.
Я внимательно изучил инструмент emscripten webidl python применительно к классу c++ Foo следующим образом.
Я бы хотел, чтобы тип утки golang был представлен через webidl так же, как класс Foo.
Это обоснование будет состоять в том, чтобы взаимодействовать с другими модулями wasm, которые загружаются в то же время, но нам нужны доступные idl, чтобы иметь возможность включать и вызывать их сортировочные заглушки. В противном случае нам понадобится какое-то средство просмотра объектов, чтобы определить, какие сигнатуры вызовов доступны из разных файлов wasm.
python /usr/lib/emscripten/tools/webidl_binder.py Foo.idl glue
This generates:
glue.cpp
glue.js
WebIDLGrammar.pkl
emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js
This generates:
output.js
output.wasm
emrun --list_browsers
emrun --browser chrome handcrafted_Foo.html
emrun --browser firefox handcrafted_Foo.html
firefox handcrafted_Foo.html &
chrome handcrafted_Foo.html &
$ cat Foo.h
#ifndef FOO_H
#define FOO_H (1)
class Foo {
public:
int getVal();
void setVal(int v);
private:
int nValue;
};
#endif
$ cat Foo.cpp
#include "Foo.h"
int Foo::getVal() {
return nValue;
}
void Foo::setVal(int v) {
nValue = v;
}
$ cat my_glue_wrapper.cpp
#include "Foo.h"
#include "glue.cpp"
$ cat Foo.idl
interface Foo {
void Foo();
long getVal();
void setVal(long v);
};
$ cat handcrafted_Foo.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebAssembly Sample</title>
</head>
<body>
<h1>Web Assembly</h1>
<div class="output">
<pre id="log"></pre>
</div>
<script src="output.js"></script>
<script>
"use strict";
function log() {
document.querySelector('#log').textContent += Array.prototype.join.call(arguments, '') + '\n';
}
Module.onRuntimeInitialized = _ => {
log(`blah `);
var f = new Module.Foo();
f.setVal(200);
alert(f.getVal());
log(`blah `);
};
</script>
</body>
</html>
@ omac777 , взаимодействие с другими языками не является целью первоначальной поддержки WebAssembly в Go 1.11.
Ok. Я понимаю, что webidl — это не краткосрочная цель, но у меня есть вопросы о том, как сделать вывод wasm полезным. Во-первых, вернемся к указанному выше классу Foo, определенному выше для использования с emscripten C++ вместе с его idl. Скажем, я создал тип утки голанг, который соответствует ему. Затем скажите, что я экспортирую эти функции как функции C, чтобы их можно было вызывать из реализаций C++ Foo SetVal и GetVal. Я знаю, что в результате это будет медленнее, но попытка получить всю реализацию, встроенную в go, будет долгосрочной целью.
Как создать foo.go.wasm.a и foo.go.wasm.so? Нужен ли для каждого foo.wasm собственный foo.go.js?
Если бы была сгенерирована библиотека, полная разных foos, то был бы сгенерирован и otherfoos.go.a.js?
Как связать go.wasm.a и go.wasm.so со сгенерированным emcc output.wasm, как указано в:
emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js foo.go.wasm otherfoos.go.wasm.a
Как связать в sdl функции, которые emcc поддерживает из wasm, например, внутри go.
Когда появится поддержка полных горутин, MAXCPUCores, каналов для wasm?
Спасибо еще раз.
@ omac777 , в Go 1.11 входит следующее:
Код Go компилируется в модуль WebAssembly и запускается в браузере, и мы можем вызывать туда-сюда JavaScript.
Не обращайте внимания на файлы *.a или *.so или взаимодействие с C, GCC, emcc или SDL. Ничего из этого не входит в рамки и не будет работать.
Когда появится поддержка полных горутин, MAXCPUCores, каналов для wasm?
Он полностью поддерживает горутины и каналы (это часть Go и требуется). WebAssembly поддерживает только одно ядро, если это то, что вы подразумеваете под MAXCPUCores
. Это не ограничение Go или поддержки WebAssembly в Go.
Так ты хочешь сказать, что я не увижу ничего подобного в ближайшее время?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go
Итак, если у нас есть веб-браузеры с 4 ядрами или 20 ядрами, сгенерированный go wasm будет использовать только одно из этих ядер в веб-браузере? Я не понимаю, как вы заявляете, что это не ограничение поддержки go или go webassembly. Вы утверждаете, что это ограничение самой спецификации WEBASSEMBLY.org?
@ omac777 - Да, я считаю, что в настоящее время это ограничение самой WebAssembly, а не реализации Go.
@ omac777 Поддержка многопоточности в WASM находится в стадии разработки, и пройдет некоторое время, прежде чем она будет выпущена в браузерах.
https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md
Так ты хочешь сказать, что я не увижу ничего подобного в ближайшее время?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go
Вероятно, в Go 1.12.
Для Go, вызывающего C/C++, я думаю, возможно, обернуть функции C в JavaScript, а затем вызвать оболочку JavaScript из Go с помощью Go 1.11.
я знаю, что это не часть (возможно) темы, но есть ли какая-либо документация/учебники по использованию WebAssembly (компиляции и т. д.) в версии go v1.11?
@SerkanSipahi , еще нет. Но перед релизом будут документы.
@SerkanSipahi Я записал шаги, которые я предпринял, чтобы заставить его работать, на https://blog.lazyhacker.com/2018/05/webassembly-wasm-with-go.html.
Также есть этот пост, все еще актуальный:
https://blog.gopheracademy.com/advent-2017/go-wasm/
мне пришло в голову, что мы (IIRC) не указали точное сопоставление (ни механизм) для того, что входит в раздел export
модуля wasm.
Я подал # 25612.
Используя цель wasm, уточните/задокументируйте, как:
-use go для экспорта/импорта функции go в wasm и из wasm для использования на других языках.
-связать sdl2/webgl/qt с бинарным файлом golang
-ловить все события sdl2/webgl/qt
-временно возвращать время процессора ОС с помощью сна, если мы находимся в цикле. Например
в emscripten emscripten_sleep(10)
Файл output.html из инструмента go, похоже, не работает последовательно как с firefox, так и с chrome, даже если был успешно построен output.html. Необходимо сделать больше, чтобы гарантировать, что output.html работает. прежде чем представить его как успех.
@ omac777 , мы рассмотрели большую часть вышеперечисленного. Но для других просто настроить:
Используя цель wasm, уточните/задокументируйте, как:
-use go для экспорта/импорта функции go в wasm и из wasm для использования на других языках.
-связать sdl2/webgl/qt с бинарным файлом golang
-ловить все события sdl2/webgl/qt
Как указано выше, ничего из этого не относится к Go 1.11. Он не будет поддерживаться, документироваться или, вероятно, даже невозможен.
-временно возвращать время процессора ОС с помощью сна, если мы находимся в цикле. Например
У @neelance есть обратные вызовы и взаимодействие между JS и планировщиком Go, поэтому обычные time.Sleep
и друзья должны работать как положено.
Я понимаю, что в Go 1.11 не будет ничего из этого, но как далеко/долго будет рассматриваться любое из вышеперечисленного для перехода. Есть люди, которые хотели бы видеть qt полностью интегрированным с go, и в настоящее время ситуация такова, что мы полагаемся на третью сторону для этого therecipe/qt, что все хорошо, но есть ограничения (в настоящее время нет wasm qt и нет qt 64-битных целей руки поддерживается). Autocad предлагает решение для веб-сборки для Windows и MacOS с использованием emscripten, C++ и React. Я все еще чувствую, что golang все еще ограничен в определенных областях использования, а не там, где можно использовать C++.
Существует много сил, которые нужно иметь, это подход С++:
emcc --clear-cache --clear-ports
em++ -v -std=c++1y hello_world_sdl.cpp -s USE_SDL=2 -s USE_SDL_IMAGE=2 EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s WASM=1 -o hello_world_sdl.html
Почему у golang не может быть подобного поведения?
ОБНОВЛЕНИЕ: я исправлен. Golang не нуждается в переключателях "-s" из-за директив компиляции cgo, встроенных в код go.
Однако очистить кеш и очистить порты — хорошая идея, так как могут возникнуть ошибки при переходе на разные версии сборки golang, например, с go1.9 на go1.10. перейти с 1.10.3 на go1.11 (когда мы перейдем на образ жизни vgo). Недавно мне пришлось сделать «go build -a» между версиями go build.
GOARCH=wasm GOOS=js go --clear-cache --clear-ports
Почему у golang не может быть подобного поведения?
GOARCH=wasm GOOS=js go --clear-cache --clear-ports
FWIW, кеш Go не требует явной очистки для корректности.
@neelance - теперь, когда есть обратные вызовы, я считаю, что базовая поддержка завершена. Закроем этот баг или вы что-то другое имели в виду?
Да, я думаю, мы можем закрыть это сейчас. 🎉
Отличная работа!!! @неланс
Это потрясающе, отличная работа @neelance!
Изменение https://golang.org/cl/120057 упоминает эту проблему: doc/go1.11: mention GOOS/GOARCH values of WebAssembly port explicitly
Изменение https://golang.org/cl/120575 упоминает эту проблему: cmd/dist: skip non-std tests on js/wasm
Уместно ли поднимать вопрос об уменьшении размера файла (если это вообще возможно)? Или это где-то отслеживается?
@matthewp , не стесняйтесь открывать ошибку размера, связанную с веб-сборкой, если хотите. Общий номер 6853.
Изменение https://golang.org/cl/120958 упоминает эту проблему: net: re-implement built-in simulated network on JS and NaCl
Имеет ли компилятор golang встроенную целостность потока управления (CFI)? Недавно я просмотрел следующее, чтобы узнать об уязвимостях в WASM, предотвращенных с помощью CFI, встроенного в компилятор clang:
https://www.fastly.com/blog/hijacking-control-flow-webassembly-program
https://github.com/trailofbits/clang-cfi-showcase/blob/master/cfi_vcall.cpp
Просто просмотрел его, но мне кажется, что в сообщении говорится: «WebAssembly — это не язык высокого уровня, такой как JavaScript, а язык низкого уровня, поэтому могут применяться определенные классы ошибок, если исходный язык (C или Go) их допускает. ." Ничего удивительного. Это означает, что если бы у Go были такие проблемы, они также относились бы к другим архитектурам, а не только к WebAssembly.
WebAssembly в основном предназначен для защиты браузера от вредоносного кода WebAssembly. Речь идет не столько о предоставлении гарантий внутри экземпляра WebAsssembly (хотя некоторые из них есть). Как сказал @neelance , компиляторы LanguageX- > WebAssembly должны предоставить любые необходимые гарантии безопасности.
В Go нет CFI. Я не думаю, что это будет легко - в точке, где начинается метод, мы уже потеряли виртуальную таблицу. Мы даже утратили тот факт, что использовалась виртуальная таблица.
Go уязвим для этого эксплойта в тех случаях, когда есть какой-либо параллелизм. На данный момент, по крайней мере, порт WebAssembly Go (и WebAssembly, точка) не имеет параллелизма, поэтому этот эксплойт является только теоретическим. Однако разработчики WebAssembly планируют в какой-то момент реализовать параллелизм.
@ randall77 Как это влияет на простой linux/amd64
? Риск как-то больше для WebAssembly?
Риск один и тот же независимо от архитектуры (за исключением того, что в WebAssembly еще нет потоков, поэтому на данный момент он фактически равен нулю для WebAssembly). Гонки данных можно использовать для имитации unsafe
без импорта unsafe
.
Было бы сложно использовать такую уязвимость. Вам нужно либо связать ненадежный код, либо каким-то образом найти и активировать гаджет в существующем двоичном файле, который выполняет гонку данных для значения интерфейса, а затем вызывает метод для результата.
Итак, если в вашем коде Go нет гонок данных, то все должно быть в порядке. Кроме того, при запуске ненадежного кода с помощью WebAssembly вы можете быть уверены, что он не сможет покинуть среду WebAssembly, даже если он может иметь гонки данных или просто использовать unsafe
. Спасибо за интересные идеи и извините за то, что это немного не по теме для этого вопроса.
Чем больше я изучаю это использование javascript изнутри golang, тем больше я воспринимаю его как инфекцию, которая ухудшит качество и долгосрочное обслуживание кода golang. Позволь мне объяснить. Вот пример замечательного приложения wasm golang, которое производит впечатляющее волшебство.
https://github.com/stdiopt/gowasm-experiments/blob/master/bouncy/main.go
Результаты впечатляют. Углубление в код, который на самом деле делает это, разочаровывает, потому что требует, чтобы каждый раз, когда вы хотите вызвать что-то со стороны javascript, вы требовали, чтобы вы описывали имя функции javascript или значение javascript в виде строки НА КАЖДОМ ХОДУ . В результате компилятор golang не может проверить правильность javascript во время компиляции. Это «летать молитвой» во время выполнения. Я бы предпочел видеть функции/переменные/типы golang везде для долгосрочного обслуживания, иначе, по моему скромному мнению, это противоречит цели использования golang для wasm. Кстати, я ненавижу javascript и всегда терпеть не мог. Это слишком вольно. Почему такой язык сохранился в веб-браузерах? Ответ ускользает от меня.
Спасибо, что выслушали.
Я согласен, что вызов JS с использованием строк не лучший опыт. Возможно, мы могли бы генерировать интерфейсы Go из спецификаций IDL веб-платформы. Недостатком является то, как не отставать от спецификации, потому что в зависимости от браузера, который будет работать, API недоступен, а с другой стороны, новые спецификации продолжают появляться все время по мере развития веб-платформы.
@ omac777 Я согласен с тобой. Вот почему я надеюсь, что вокруг низких уровней JS будут хорошие библиотеки Go, чтобы большинству пользователей никогда не приходилось напрямую прикасаться к syscall/js
. Подобно пакету syscall
, он уродлив, и почти никто не использует его напрямую. ;-)
@ omac777 Для GopherJS многие люди используют высокоуровневые привязки для различных API-интерфейсов браузера, а не напрямую низкоуровневый пакет js
. Я подозреваю, что подобный подход будет наиболее популярен и в Wasm. Я ожидаю, что многие привязки GopherJS добавят поддержку Wasm в том же пакете, и новые пакеты будут создаваться по мере необходимости.
Для справки см. https://github.com/gopherjs/gopherjs/wiki/Bindings , https://dmitri.shuralyov.com/talks/2016/Go-in-the-browser/Go-in-the-browser. слайд № 11 (и следующие 4 слайда) и https://github.com/dominikh/go-js-dom/issues/57.
Также мы должны учитывать, что в дорожной карте webassembly есть куча вещей:
https://webassembly.org/docs/future-features/
это значительно улучшит историю syscall
в долгосрочной перспективе, например
ссылаться на DOM и другие объекты веб-API непосредственно из кода WebAssembly;
вызывать веб-API (передавая примитивы или объекты DOM/GC/веб-API) непосредственно из WebAssembly без вызова через JavaScript; а также
эффективно выделять и управлять объектами GC непосредственно из кода WebAssembly.
В любом случае, спасибо @neelance et. др. для реализации начальной версии. Так круто! 🥇
Что, если бы существовала реализация DOM на Go?
Документы и сценарии можно писать и выполнять на Go, используя систему типов.
Затем код может быть сгенерирован из Go DOM.
@fractalbach : если привязка хоста WebAssembly подтверждена и реализована рабочей группой, вы действительно можете выполнять манипуляции с DOM через WebAssembly. Тогда было бы разумно иметь библиотеки высокого уровня для абстрагирования DOM, документов и скриптов.
Но до этого это не так привлекательно.
Go WebAssembly: привязка структур к ссылкам JS
https://medium.com/@nlepage/go-webassembly-binding-structures-to-js-references-4eddd6fd4d23
Подход привлекательный. Использование похоже на сортировку/десортировку json внутри структур. Это делает его легко передаваемым навыком.
Единственное, чего не хватает, так это того, как применить тот же подход к дак-печати? Я бы предпочел не иметь объявления функций внутри структуры, а вне ее автономно, таким же образом, как и утиная печать. Если сервис существует, он может его использовать. Таким образом, его легко модифицировать, не затрагивая основную структуру, содержащую различные желаемые нефункциональные значения. Печатающие утки скалы!
Еще раз спасибо @neelance за всю вашу работу. Это очень ценится.
Спасибо, г-н Николя Лепаж, за вашу точку зрения. Они действительно помогают определить, что может быть лучшим путем для взаимодействия со всем этим шумом javascript на промежуточный период, пока не будет завершено прямое взаимодействие wasm.
Привет всем, это тема с высоким трафиком, на которую подписано много людей. Подобное общее обсуждение не принесет пользы тем, кого интересует только первоначальный вопрос, а именно наличие поддержки WebAssembly для Go.
Пожалуйста, не стесняйтесь продолжать обсуждение на соответствующих форумах - golang-nuts/golang-dev. Или, если у вас есть что-то конкретное, пожалуйста, откройте новый вопрос.
Спасибо.
Самый полезный комментарий
Всем привет. Вот обновленная информация о моей работе: я делаю очень хорошие успехи, во многом благодаря отличной работе команды Go и участников. Большая часть кода является общей для разных архитектур/платформ, поэтому не так много, как я ожидал, нужно было реализовать.
Вот список некоторых вещей, которые уже работают нормально:
bytes, container/heap, container/list, container/ring, encoding/ascii85, encoding/asn1, encoding/base32, encoding/binary, encoding/csv, encoding/hex, errors, flag, hash/adler32, hash/crc32, hash/crc64, hash/fnv, html, image, image/color, index/suffixarray, math, math/bits, path, sort, strconv, strings, text/scanner, text/tabwriter, unicode, unicode/utf8, unicode/utf16
Некоторые вещи, над которыми еще нужно поработать:
Я очень доволен прогрессом за полтора месяца, и то только в свободное время. Я думаю, есть хороший шанс, что мы сможем включить это в Go 1.11. Ожидайте моего следующего обновления в январе, так как я буду в отпуске, а потом будут праздники.