Zostało zaprezentowane trzecie istotne wydanie projektu Wasmer, rozwijającego runtime do uruchamiania modułów WebAssembly, który można wykorzystać do tworzenia uniwersalnych aplikacji mogących działać w różnych systemach operacyjnych, jak również do izolowanego wykonania kodu, który nie zasługuje na zaufanie. Kod projektu napisany jest w języku Rust i jest rozpowszechniany na licencji MIT.
Możliwość uruchamiania jednej aplikacji na różnych platformach zapewniana jest dzięki kompilacji kodu do niskopoziomowego kodu pośredniego WebAssembly, który może być uruchamiany w dowolnych systemach operacyjnych lub wbudowywany w programy w innych językach programowania. Aplikacje są lekkimi kontenerami, w których uruchamiany jest pseudokod WebAssembly. Te kontenery nie są związane z systemem operacyjnym i mogą zawierać kod, który był pierwotnie napisany w dowolnym języku programowania. Do kompilacji do WebAssembly może być używane narzędzie Emscripten. Do translacji WebAssembly na kod maszynowy bieżącej platformy wspierane jest podłączenie różnych backendów kompilacji (Singlepass, Cranelift, LLVM) i silników (wykorzystanie JIT lub generacja kodu maszynowego).
Aplikacje są izolowane od głównego systemu w środowisku sandbox i mają dostęp tylko do zadeklarowanej funkcjonalności (mechanizm bezpieczeństwa oparty na zarządzaniu możliwościami – do działań z każdym z zasobów (pliki, katalogi, gniazda, wywołania systemowe itp.) aplikacji muszą być przyznane odpowiednie uprawnienia). Zarządzanie dostępem i interakcja z systemem są zapewniane przy pomocy API WASI (WebAssembly System Interface), które dostarcza interfejsy programowe do pracy z plikami, gniazdami i innymi funkcjami udostępnianymi przez system operacyjny.
Platforma pozwala osiągnąć wydajność wykonywania aplikacji bliską wykonaniu natywnych kompilacji. Za pomocą Native Object Engine dla modułu WebAssembly można wygenerować kod maszynowy („wasmer compile --native” do generowania wstępnie skompilowanych plików obiektowych .so, .dylib i .dll), do uruchomienia którego wymagany jest minimalny runtime, ale zachowane są wszystkie możliwości izolacji sandbox. Istnieje możliwość dostarczenia wstępnie skompilowanych programów z wbudowanym Wasmerem. Do tworzenia nakładek i rozszerzeń oferowane są interfejsy API Rust i Wasm-C-API.
Aby uruchomić kontener WebAssembly, wystarczy zainstalować w systemie runtime Wasmer, który jest dostarczany bez zewnętrznych zależności ("curl https://get.wasmer.io -sSfL | sh"), a następnie uruchomić odpowiedni plik ("wasmer test.wasm"). Programy są dystrybuowane w postaci zwykłych modułów WebAssembly, którymi można zarządzać za pomocą menedżera pakietów WAPM. Wasmer jest również dostępny w formie biblioteki, którą można wykorzystać do wbudowywania kodu WebAssembly w programy w językach Rust, C/C++, C#, D, Python, JavaScript, Go, PHP, Ruby, Elixir i Java.
Główne zmiany w Wasmer 3.0:
- Dodano możliwość tworzenia natywnych plików wykonywalnych dla dowolnych platform. Została całkowicie przeprojektowana komenda „wasmer create-exe”, która pozwala przekształcić plik z pośrednim kodem WebAssembly w samowystarczalne pliki wykonywalne dla platform Linux, Windows i macOS, które mogą działać bez instalacji samego Wasmer.
- Umożliwiono uruchamianie pakietów WAPM umieszczonych w katalogu wapm.io przy użyciu komendy „wasmer run”. Na przykład, wykonanie „wasmer run python/python” spowoduje załadowanie z repozytorium wapm.io pakietu python i jego uruchomienie.
- Całkowicie przeprojektowano API Wasmer Rust, w którym zmieniono styl pracy z pamięcią i zapewniono możliwość bezpiecznego przechowywania obiektów Wasm w strukturze Store. Zaproponowano nową strukturę MemoryView, która umożliwia odczyt i zapis danych w liniowej przestrzeni pamięci.
- Zrealizowano zestaw komponentów wasmer-js do uruchamiania Wasmer w przeglądarce internetowej i interakcji z nim z poziomu JavaScript, korzystając z biblioteki wasm-bindgen. Pod względem funkcjonalności wasmer-js odpowiada komponentom wasmer-sys, które są przeznaczone do uruchamiania Wasmer w standardowych systemach operacyjnych.
- Uproszczono silniki. Zamiast oddzielnych silników do JIT, dynamicznego i statycznego wiązania (Universal, Dylib, StaticLib), teraz oferowany jest jeden wspólny silnik, a ładowanie i zapisywanie kodu jest zarządzane na poziomie ustawienia parametrów.
- Do deserializacji artefaktów zastosowano framework rkyv, który zapewnia działanie w trybie zero-copy, tzn. nie wymaga alokacji dodatkowej pamięci i wykonuje deserializację tylko przy użyciu pierwotnie dostarczonego bufora. Wykorzystanie rkyv znacznie zwiększyło prędkość uruchamiania.
- Ulepszony kompilator jednoprzebiegowy Singlepass, który zyskał wsparcie dla funkcji z wieloma argumentami (multi-value), zwiększoną niezawodność działania oraz dodane wsparcie dla klatek obsługi wyjątków.
- Ulepszona realizacja interfejsu API WASI (WebAssembly System Interface). Rozwiązano problemy z interfejsem WASI do pracy z systemem plików. Wewnętrzne typy zostały przeprojektowane z użyciem WAI (WebAssembly Interfaces), co w przyszłości umożliwi wprowadzenie serii nowych możliwości.
Źródło: opennet.ru
