Прогуливая вас через поддержку WASI в ходе

Прогуливая вас через поддержку 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Анкет Он инструктирует компилятор перевести вызовы в аннотированную функцию в вызов функции, указанной именем модуля хоста и именем функции. Эта новая функциональность компилятора - это то, что позволило нам определитьwasip1SYSCALL 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 может выполнять, в то время как другой считывает или записывает, но любые вызовы функции хоста (например, запрос случайных данных, используя пример выше), приведет к тому, что все пластинки будут блокировать, пока вызов функции хоста не будет возвращен.

Заметная отсутствующая функция вwasip1API - это полная реализация сетевых розетков.wasip1Только определяет функции, которые работают на уже открытых розетках, что делает невозможным поддержать некоторые из самых популярных функций стандартной библиотеки GO, таких как HTTP -серверы. Хосты, такие как Васмер и Васмеджа, продюсируют расширенияwasip1API, позволяя открыть сетевые розетки.

Хотя эти расширения не реализованы компилятором 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. Мы с нетерпением ждем вашего ответа!


Йохан Брандхорст-Сацкорн, Жюльен Фабр, Дамиан Гриски, Эван Феникс и Ахилль Руссель

Эта статья доступна наБлог GOПод CC по лицензии 4,0.

ФотоНеомнаНеспособный


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE