WebAssembly
Paradygmat | ustrukturyzowany ; maszyna stosowa |
---|---|
Zaprojektowany przez | W3C |
Deweloper | |
Po raz pierwszy pojawiły się | marzec 2017 |
system operacyjny | Niezależna od platformy |
Licencja | Licencja Apache 2.0 |
Rozszerzenia nazw plików |
|
Strona internetowa | |
Wpływem | |
WebAssembly (czasami w skrócie Wasm ) definiuje przenośny format kodu binarnego i odpowiedni format tekstowy dla programów wykonywalnych, a także interfejsy oprogramowania ułatwiające interakcje między takimi programami a ich środowiskiem hosta.
Głównym celem WebAssembly jest umożliwienie aplikacji o wysokiej wydajności na stronach internetowych , „ale nie przyjmuje żadnych założeń dotyczących sieci ani nie zapewnia funkcji specyficznych dla sieci, więc może być stosowany również w innych środowiskach”. Jest to otwarty standard i ma na celu obsługę dowolnego języka w dowolnym systemie operacyjnym, aw praktyce wszystkie najpopularniejsze języki mają już przynajmniej pewien poziom wsparcia.
Zapowiedziany w 2015 World Wide Web Consortium 5 grudnia 2019 i otrzymał nagrodę Programming Languages Software Award od ACM SIGPLAN w 2021. Konsorcjum World Wide Web ( W3C) utrzymuje standard dzięki wkładom Mozilli , Microsoft , Google , Apple , Fastly , Intela i Red Hata .
i wydany po raz pierwszy w marcu 2017 , WebAssembly stał się rekomendacjąHistoria
WebAssembly został nazwany, aby przywołać koncepcję języka asemblera , termin, który pochodzi z lat pięćdziesiątych XX wieku. Nazwa sugeruje przeniesienie programowania przypominającego asembler do sieci , gdzie będzie ono wykonywane po stronie klienta — przez komputer użytkownika witryny za pośrednictwem przeglądarki internetowej użytkownika . Aby to osiągnąć, WebAssembly musi być znacznie bardziej niezależny od sprzętu niż prawdziwy język asemblera.
WebAssembly został po raz pierwszy ogłoszony w 2015 roku, a pierwszą demonstracją było wykonanie Angry Bots Unity w Firefox , Google Chrome i Microsoft Edge . Prekursorowymi technologiami były asm.js z Mozilli i Google Native Client , a początkowa implementacja była oparta na zestawie funkcji asm.js. Technologia asm.js zapewnia niemal natywną prędkość wykonywania kodu i może być uważana za realną alternatywę dla przeglądarek, które nie obsługują WebAssembly lub mają ją wyłączoną ze względów bezpieczeństwa.
ogłoszono zakończenie projektowania produktu o minimalnej żywotności (MVP) i zakończono fazę podglądu. Pod koniec września 2017 r. Safari 11 zostało wydane ze wsparciem. W lutym 2018 r. grupa robocza WebAssembly opublikowała trzy publiczne wersje robocze specyfikacji podstawowej, interfejsu JavaScript i interfejsu API sieci Web.
W czerwcu 2019 roku wydano Chrome 75 z domyślnie włączonymi wątkami WebAssembly.
Od kwietnia 2022 r. WebAssembly 2.0 jest w wersji roboczej, co dodaje wiele instrukcji związanych z SIMD i nowy typ danych v128, możliwość zwracania wielu wartości przez funkcje oraz inicjowanie/kopiowanie pamięci masowej.
Implementacje
Chociaż WebAssembly został początkowo zaprojektowany w celu umożliwienia niemal natywnej szybkości wykonywania kodu w przeglądarce internetowej, uznano go za wartościowy poza takimi, w bardziej ogólnych kontekstach. Ponieważ środowiska wykonawcze WebAssembly (RE) to maszyny wirtualne niskiego poziomu (podobne do JVM lub Flash VM ), które można osadzić w aplikacjach hosta, niektóre z nich znalazły sposób na samodzielne środowiska wykonawcze, takie jak Wasmtime i Wasmer.
Przeglądarki internetowe
W listopadzie 2017 Mozilla zadeklarowała wsparcie „we wszystkich głównych przeglądarkach”, po tym jak WebAssembly zostało domyślnie włączone w Edge 16. Wsparcie obejmuje mobilne przeglądarki internetowe na iOS i Androida. Według stanu na październik 2022 r. 96% zainstalowanych przeglądarek obsługuje WebAssembly (wersja 1.0). Jednak w przypadku starszych przeglądarek Wasm można skompilować do pliku asm.js za pomocą kodu JavaScript polyfill .
Kompilatory
Implementacje WebAssembly zwykle używają kompilacji z wyprzedzeniem (AOT) lub just-in-time (JIT), ale mogą również korzystać z interpretera . Podczas gdy pierwsze implementacje trafiły do przeglądarek internetowych , istnieją również implementacje inne niż przeglądarki do użytku ogólnego, w tym Wasmer, Wasmtime lub WAMR, wasm3, WAVM i wiele innych.
Ponieważ pliki wykonywalne WebAssembly są wstępnie skompilowane, do ich tworzenia można używać różnych języków programowania. Osiąga się to albo poprzez bezpośrednią kompilację do Wasm, albo poprzez implementację odpowiednich maszyn wirtualnych w Wasm. Zgłoszono około 40 języków programowania obsługujących Wasm jako cel kompilacji.
Emscripten kompiluje C i C++ do Wasm, używając Binaryen i LLVM jako zaplecza. Emscripten SDK może skompilować kod źródłowy dowolnego języka obsługiwanego przez LLVM (takiego jak między innymi C , C++ lub Rust ) do pliku binarnego, który działa w tej samej piaskownicy co kod JavaScript. Emscripten zapewnia powiązania dla kilku często używanych interfejsów środowiskowych, takich jak WebGL .
Od wersji 8 samodzielny Clang może kompilować C i C++ do Wasm.
Jego początkowym celem jest wspieranie kompilacji z C i C++ , chociaż pojawia się również wsparcie dla innych języków źródłowych , takich jak Rust , języki .NET i AssemblyScript ( podobny do TypeScript ). Po wydaniu MVP planuje się obsługę wielowątkowości i wyrzucania elementów bezużytecznych , co uczyniłoby WebAssembly celem kompilacji dla języków programowania z wyrzucaniem elementów bezużytecznych, takich jak C# (obsługiwany przez Blazor ), F# (obsługiwane przez Bolero z pomocą Blazora), Pythona , a nawet JavaScriptu , gdzie prędkość kompilacji just-in-time przeglądarki jest uważana za zbyt niską. Niektóre inne języki są obsługiwane, w tym Python , Julia i Ruby .
Ograniczenia
- Ogólnie WebAssembly nie pozwala na bezpośrednią interakcję z DOM . Cała interakcja musi przebiegać przez JavaScript interop.
- Brak zbierania elementów bezużytecznych (chociaż istnieją plany rozwiązania tego problemu).
- Względy bezpieczeństwa (omówione poniżej)
WebAssembly jest obsługiwany na komputerach stacjonarnych i urządzeniach mobilnych, ale w przypadku tych ostatnich w praktyce (w przypadku mniejszych alokacji pamięci, takich jak silnik gry Unity ) istnieją „poważne ograniczenia, które uniemożliwiają niezawodne wdrożenie wielu aplikacji w przeglądarkach mobilnych [. .] Obecnie przydzielanie ponad ~300 MB pamięci nie jest niezawodne w Chrome na Androida bez uciekania się do obejść specyficznych dla Chrome, ani w Safari na iOS”.
Nie ma bezpośredniego dostępu do Document Object Model (DOM); jednak możliwe jest utworzenie w tym celu funkcji proxy, na przykład przez stdweb lub web_sys, gdy używany jest język Rust .
Wszystkie główne przeglądarki internetowe zezwalają na WebAssembly, jeśli nie określono Content-Security-Policy lub jeśli użyto „unsafe-eval”, ale poza tym główne przeglądarki internetowe zachowują się inaczej. W praktyce WebAssembly nie może być używany w Chrome bez „unsafe-eval”, podczas gdy dostępne jest obejście wątku roboczego.
Względy bezpieczeństwa
W czerwcu 2018 roku badacz bezpieczeństwa przedstawił możliwość wykorzystania WebAssembly do obejścia zabezpieczeń przeglądarek pod kątem luk w zabezpieczeniach Spectre i Meltdown po dodaniu obsługi wątków z pamięcią współdzieloną. Ze względu na ten problem programiści WebAssembly wstrzymali tę funkcję. Jednak w celu zbadania tych przyszłych rozszerzeń językowych Google Chrome dodał eksperymentalną obsługę propozycji wątku WebAssembly w październiku 2018 r.
WebAssembly był krytykowany za umożliwienie większej łatwości ukrywania dowodów dla twórców złośliwego oprogramowania, oszustów i osób atakujących phishingiem ; WebAssembly jest obecny na komputerze użytkownika tylko w skompilowanej formie, co „[utrudnia wykrywanie złośliwego oprogramowania]”. Szybkość i możliwość ukrycia WebAssembly doprowadziły do jego wykorzystania w ukrytym wydobywaniu kryptowalut na urządzeniu odwiedzającego witrynę. Coinhive , nieistniejąca już usługa ułatwiająca wydobywanie kryptowalut w przeglądarkach odwiedzających witrynę, twierdzi, że ich „górnik używa WebAssembly i działa z około 65% wydajnością natywnego górnika”. Badanie przeprowadzone w czerwcu 2019 r. przez Technische Universität Braunschweig przeanalizowało użycie WebAssembly w 1 milionie najpopularniejszych witryn internetowych Alexa i wykazało, że dominującym zastosowaniem było złośliwe wydobywanie kryptowalut, a to złośliwe oprogramowanie stanowiło ponad połowę badanych witryn internetowych korzystających z WebAssembly. Badanie przeprowadzone w kwietniu 2021 r. przez Universität Stuttgart odkrył, że od tego czasu wydobywanie kryptowalut zostało zmarginalizowane, spadając do poziomu poniżej 1% wszystkich modułów WebAssembly zebranych z wielu różnych źródeł, w tym także z 1 miliona najpopularniejszych witryn Alexa.
Zdolność do skutecznego zaciemniania dużych ilości kodu można również wykorzystać do wyłączenia blokowania reklam i narzędzi do ochrony prywatności, które zapobiegają śledzeniu w sieci, takich jak Privacy Badger .
Ponieważ WebAssembly obsługuje tylko ustrukturyzowany przepływ sterowania , jest podatny na techniki weryfikacji bezpieczeństwa, w tym wykonanie symboliczne . Obecne wysiłki w tym kierunku obejmują symboliczny silnik wykonawczy Manticore.
CZY BYŁEM
WebAssembly System Interface (WASI) to prosty interfejs ( ABI i API ) zaprojektowany przez Mozillę , który ma być przenośny na dowolną platformę. Zapewnia POSIX , takie jak operacje we/wy plików ograniczone przez zabezpieczenia oparte na możliwościach . Istnieje również kilka innych proponowanych interfejsów ABI/API.
WASI jest pod wpływem CloudABI i Capsicum .
Solomon Hykes, współzałożyciel Dockera , napisał w 2019 roku: „Gdyby WASM+WASI istniało w 2008 roku, nie musielibyśmy tworzyć Dockera. To jest takie ważne. WebAssembly na serwerze to przyszłość informatyki”. Wasmer w wersji 1.0 zapewnia „konteneryzację oprogramowania, tworzymy uniwersalne pliki binarne, które działają w dowolnym miejscu bez modyfikacji, w tym w systemach operacyjnych takich jak Linux, macOS, Windows i przeglądarki internetowe. Wasm domyślnie automatycznie umieszcza aplikacje w piaskownicy w celu bezpiecznego wykonania”.
Specyfikacja
Środowisko hosta
Ogólny standard zawiera podstawowe specyfikacje interfejsu API języka JavaScript oraz szczegółowe informacje na temat osadzania.
Maszyna wirtualna
Kod wasm (kod binarny, tj. kod bajtowy) jest przeznaczony do uruchamiania na przenośnej maszynie wirtualnego stosu (VM). Maszyna wirtualna została zaprojektowana tak, aby była szybsza do analizowania i wykonywania niż JavaScript oraz miała zwartą reprezentację kodu. Zewnętrzna funkcjonalność (taka jak syscalls ), której można oczekiwać od kodu binarnego Wasm, nie jest określona w standardzie. Zapewnia raczej sposób dostarczania interfejsu za pośrednictwem modułów przez środowisko hosta, w którym działa implementacja maszyny wirtualnej.
Program Wasm
Program Wasm ma być oddzielnym modułem zawierającym kolekcje różnych wartości zdefiniowanych przez Wasm i definicje typów programów. Są one wyrażone w formacie binarnym lub tekstowym (patrz poniżej), które mają wspólną strukturę.
Zestaw instrukcji
Podstawowy standard formatu binarnego programu Wasm definiuje architekturę zestawu instrukcji (ISA) składającą się z określonych kodowań binarnych typów operacji wykonywanych przez maszynę wirtualną (bez określania, jak dokładnie muszą być wykonywane). Lista instrukcji obejmuje standardowe instrukcje ładowania/przechowywania pamięci, instrukcje numeryczne, parametryczne, kontrolujące typy instrukcji przepływu oraz instrukcje zmienne specyficzne dla Wasm.
Liczba kodów operacji użytych w oryginalnym standardzie (MVP) była nieco mniejsza niż 200 z 256 możliwych kodów operacji. Kolejne wersje WebAssembly zwiększyły liczbę kodów operacji nieco ponad 200. SIMD WebAssembly (do przetwarzania równoległego) wprowadza alternatywny prefiks kodu operacji (0xfd) dla 128-bitowego SIMD. Konkatenacja prefiksu SIMD plus opcode, który jest ważny po prefiksie SIMD, tworzy opcode SIMD. Kody operacyjne SIMD zapewniają dodatkowe 236 instrukcji dla funkcji SIMD „minimalnego opłacalnego produktu” (MVP) (łącznie około 436 instrukcji). Instrukcje te, „sfinalizowane opcodes”, są zaimplementowane w Google V8 (w Google Chrome) i w odpowiednim silniku w Mozilla Firefox (ale nie są włączone w stabilnych wersjach przeglądarek internetowych), a także istnieje kilka dodatkowych propozycji instrukcji na później „post SIMD MVP”, a na stole jest też oddzielna propozycja „relaxed-simd”.
Te kody operacyjne SIMD są również przenośne i tłumaczą na natywne zestawy instrukcji, takie jak x64 i ARM. W przeciwieństwie do tego, ani JVM Javy (ani CIL ) nie obsługują SIMD na swoim poziomie kodu operacji , tj. w standardzie; oba mają kilka równoległych interfejsów API, które zapewniają przyspieszenie SIMD. Istnieje rozszerzenie dla Javy, dodające elementy wewnętrzne dla SIMD x64, które nie jest przenośne, tj. nie nadaje się do użytku na ARM ani smartfonach. Smartfony mogą obsługiwać SIMD, wywołując kod asemblera z SIMD, a C# ma podobną obsługę.
Reprezentacja kodu
W marcu 2017 r. WebAssembly Community Group osiągnęła konsensus w sprawie początkowego formatu binarnego (MVP), API JavaScript i interpretera referencyjnego. Definiuje binarny format WebAssembly ( .wasm
), który nie jest przeznaczony do użytku przez ludzi, a także czytelny dla człowieka format tekstowy WebAssembly ( . wat
), który przypomina skrzyżowanie S-wyrażeń i tradycyjnych języków asemblera.
Poniższa tabela przedstawia przykład funkcji silni napisanej w C i odpowiadającego jej kodu WebAssembly po kompilacji, przedstawionej zarówno w formacie tekstowym .wat (czytelna tekstowa reprezentacja WebAssembly), jak i w formacie binarnym .wasm (nieprzetworzony kod bajtowy , wyrażony poniżej w postaci szesnastkowej ), która jest wykonywana przez przeglądarkę internetową lub środowisko wykonawcze obsługujące WebAssembly.
kod źródłowy C | Format tekstowy WebAssembly .wat | Format binarny WebAssembly .wasm |
---|---|---|
0
int silnia ( int n ) { if ( n == ) return 1 ; w przeciwnym razie zwróć n * silnia ( n -1 ); }
|
0
0
0
0
( func ( parametr i64 ) ( wynik i64 ) local.get i64.eqz if ( wynik i64 ) i64.const 1 else local.get local.get i64.const 1 i64.sub wywołanie i64.mul koniec )
|
00 61 73 6D 01 00 00 00 01 06 01 60 01 7E 01 7E 03 02 01 00 0A 17 01 15 00 20 00 50 04 7E 42 01 05 20 00 20 00 42 01 7D 1 0 00 7E 0B 0B |
Wszystkie stałe całkowite są kodowane przy użyciu oszczędnego przestrzennie kodowania LEB128 o zmiennej długości.
Format tekstowy WebAssembly jest bardziej kanonicznie zapisany w formacie składanym przy użyciu S-expressions . W przypadku instrukcji i wyrażeń ten format jest czysto syntaktyczny i nie różni się zachowaniem od formatu liniowego. Poprzez wasm2wat
powyższy kod dekompiluje się do:
( moduł ( wpisz $t0 ( func ( param i64 ) ( wynik i64 ))) ( func $f0 ( wpisz $t0 ) ( param $p0 i64 ) ( wynik i64 ) ( if $I0 ( wynik i64 ) ;; $I0 to nieużywana nazwa etykiety ( i64.eqz ( local.get $p0 ))
;; nazwa $p0 jest tutaj taka sama jak 0 ( wtedy ( i64.const 1 )) ( else ( i64.mul ( local.get $p0 ) ( call $f0 ;; nazwa $f0 jest tutaj taka sama jak 0 ( i64 .sub ( local.get $p0 ) ( i64.const 1 ))))))))
Należy zauważyć, że moduł jest niejawnie generowany przez kompilator. Funkcja jest faktycznie przywoływana przez wpis tabeli typów w pliku binarnym, stąd sekcja typu i typ emitowany
przez dekompilator. Kompilator i dekompilator są dostępne online.
Notatki
Zobacz też
- Architektoniczny neutralny format dystrybucji (ANDF)
- UKOŁ
- Kod bajtowy Javy
- Środowisko uruchomieniowe języka wspólnego
- LLVM
- Kompilacja
- Przenośność oprogramowania
Ten artykuł zawiera tekst z bezpłatnej pracy nad treścią. Licencjonowany w ramach Apache License 2.0 ( oświadczenie licencyjne/pozwolenie ). Tekst zaczerpnięty z Text Format <a i=6>, chrom Rossberga; kripken; tizer; s3thompson; kod sunfish; Lukewagnera; flagxor; enricobacis; c3d; binji; andrewosh, GitHub. WebMontaż/projekt.
Linki zewnętrzne
- Oficjalna strona internetowa
- Grupa społecznościowa W3C
- Projektowanie WebAssembly
- „WebAssembly” , MDN Web Docs - z informacjami na temat kompatybilności i specyfikacji przeglądarki (WebAssembly JavaScript API)