
Прогуливая вас через поддержку WASI в ходе
21 июля 2025 г.GO 1.21 добавляет новый порт, нацеленный на API WASI Preview 1 SYSCALL через новыйGOOS
ценитьwasip1
Анкет Этот порт основан на существующем порту Webassembly, представленном в GO 1.11.
Что такое webassembly?
Webassembly (wasm)это бинарный формат инструкций, изначально предназначенный для Интернета. Он представляет собой стандарт, который позволяет разработчикам запускать высокопроизводительный, низкоуровневый код непосредственно в веб-браузерах на почти костюмах.
Первоначально добавлена поддержка для компиляции в WASM в выпуске 1.11 черезjs/wasm
порт Это позволило Code Go, скомпилированным с использованием компилятора GO для выполнения в веб -браузерах, но для этого потребовалась среда выполнения JavaScript.
По мере роста использования WASM, так что есть варианты использования за пределами браузера. Многие облачные провайдеры теперь предлагают услуги, которые позволяют пользователю напрямую выполнять исполнительные файлы WASM, используя новыеСистемный интерфейс Webassembly (WASI)Syscall API.
Системный интерфейс Webassembly
WASI определяет API SYSCALL для исполняемых файлов WASM, позволяя им взаимодействовать с системными ресурсами, такими как файловая система, системные часы, утилиты случайных данных и многое другое. Последний выпуск Spec Spec называетсяwasi_snapshot_preview1
, из которого мы получаемGOOS
имяwasip1
Анкет Разрабатываются новые версии API, и поддержка их в компиляторе GO в будущем, вероятно, будет означать добавление новогоGOOS
Анкет
Создание WASI позволило ряду Runtimes (хост) Wasm (хосты) стандартизировать свой Syscall API вокруг него. Примеры хостов WASM/WASI включаютWasmtimeВВазероВВасмеджаВВасмер, иNodejsАнкет Есть также ряд облачных провайдеров, предлагающих хостинг исполняемых файлов WASM/WASI.
Как мы можем использовать его с Go?
Убедитесь, что вы установили хотя бы версию 1.21 GO. Для этой демонстрации мы будем использоватьВедущий Wasmtimeвыполнить наш двоичный файл. Давайте начнем с простогоmain.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
Мы можем построить это дляwasip1
Используя команду:
$ GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
Это создаст файл,main.wasm
С чем мы можем выполнитьwasmtime
:
$ wasmtime main.wasm
Hello world!
Это все, что нужно, чтобы начать работу с Wasm/Wasi! Вы можете ожидать почти всех функций, чтобы просто работать сwasip1
Анкет Чтобы узнать больше о деталях того, как работает Wasi, пожалуйста, посмотритепредложениеАнкет
Тесты на бег с wasip1
GO 1.24 переместил файлы поддержки WASM на
lib/wasm
Анкет Для GO 1.21 - 1,23, используйтеmisc/wasm
каталог.
Создать и управлять бинарнымgo test
непосредственно без необходимости строить и выполнять бинарную вручную. Похоже наjs/wasm
Порт, стандартное библиотечное распространение, включенное в вашу установку GO, поставляется с файлом, который делает его очень простым. Добавитьlib/wasm
каталог на вашPATH
При запуске тестирования GO, и он запустит тесты, используя хост WASM по вашему выбору. Это работаетgo test
автоматическое выполнениеlib/wasm/go_wasip1_wasm_exec
Когда он находит этот файл вPATH
Анкет
$ export PATH=$PATH:$(go env GOROOT)/lib/wasm
$ GOOS=wasip1 GOARCH=wasm go test ./...
Это будет работатьgo test
Используя wasmtime. Используемый хост WASM можно контролировать с помощью переменной средыGOWASIRUNTIME
Анкет Поддерживаемые в настоящее время значения для этой переменнойwazero
Вwasmedge
Вwasmtime
, иwasmer
Анкет Этот сценарий подлежит нарушению изменений между версиями GO. Обратите внимание, что идиwasip1
двоичные файлы пока не выполняются на всех хостах (см.#59907и#60097)
Эта функциональность также работает при использованииgo run
:
$ GOOS=wasip1 GOARCH=wasm go run ./main.go
Hello world!
Обертывание функций WASM в Go Go Go: wasmimport
В дополнение к новомуwasip1/wasm
Порт, GO 1.21 представляет новую директиву компилятора:go:wasmimport
Анкет Он инструктирует компилятор перевести вызовы в аннотированную функцию в вызов функции, указанной именем модуля хоста и именем функции. Эта новая функциональность компилятора - это то, что позволило нам определитьwasip1
SYSCALL API в Go, чтобы поддержать новый порт, но он не ограничивается использованием в стандартной библиотеке.
Например, API wasip1 syscall определяетrandom_get
функция, и она подвергается значению стандартной библиотеки GOфункциональная оберткаОпределено в пакете выполнения. Похоже, это:
//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
func random_get(buf unsafe.Pointer, bufLen size) errno
Эта функциональная обертка затем завернута вболее эргономичная функцияДля использования в стандартной библиотеке:
func getRandomData(r []byte) {
if random_get(unsafe.Pointer(&r[0]), size(len(r))) != 0 {
throw("random_get failed")
}
}
Таким образом, пользователь может позвонитьgetRandomData
с байтовым ломтиком, и в конечном итоге он пройдет к ведущему хозяинуrandom_get
функция Точно так же пользователи могут определить свои собственные обертки для функций хоста.
Чтобы узнать больше о тонкостях функций упаковки WASM, пожалуйста, посмотритеаgo:wasmimport
предложение.
Ограничения
Покаwasip1
Порт проходит все стандартные библиотечные тесты, существуют некоторые заметные фундаментальные ограничения архитектуры WASM, которые могут удивить пользователей.
WASM - это единственная резьбовая архитектура без параллелизма. Планировщик по-прежнему может запланировать Goroutines для выполнения одновременно, а стандартная внедрение/Out/Orir не блокирует, поэтому Goroutine может выполнять, в то время как другой считывает или записывает, но любые вызовы функции хоста (например, запрос случайных данных, используя пример выше), приведет к тому, что все пластинки будут блокировать, пока вызов функции хоста не будет возвращен.
Заметная отсутствующая функция вwasip1
API - это полная реализация сетевых розетков.wasip1
Только определяет функции, которые работают на уже открытых розетках, что делает невозможным поддержать некоторые из самых популярных функций стандартной библиотеки GO, таких как HTTP -серверы. Хосты, такие как Васмер и Васмеджа, продюсируют расширенияwasip1
API, позволяя открыть сетевые розетки.
Хотя эти расширения не реализованы компилятором GO, существует сторонняя библиотека,github.com/stealthrocket/net
, который используетgo:wasmimport
Чтобы использоватьnet.Dial
иnet.Listen
на поддерживаемых хостах WASM. Это позволяет создаватьnet/http
серверы и другие функциональность, связанные с сетью при использовании этого пакета.
Будущее Wasm in go
Добавлениеwasip1/wasm
Порт - это только начало возможностей WASM, которые мы хотели бы подвести. Пожалуйста, следите заПроблема трекераДля предложений о экспорте функций GO в WASM (go:wasmexport
), 32-битный порт и будущая совместимость API API.
Принять участие
Если вы экспериментируете и хотите внести свой вклад в WASM и уйти, пожалуйста, примите участие! The Go выпуск трекеров отслеживает все работы и канал #webassembly наСуслики слабыеэто отличное место для обсуждения Go и Webassembly. Мы с нетерпением ждем вашего ответа!
Йохан Брандхорст-Сацкорн, Жюльен Фабр, Дамиан Гриски, Эван Феникс и Ахилль Руссель
Эта статья доступна на
ФотоНеомнаНеспособный
Оригинал