웹어셈블리

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

웹어셈블리(WebAssembly, Wasm)는 웹 브라우저에서 네이티브에 가까운 속도로 코드를 실행하기 위해 설계된 바이너리 형식의 명령어 집합이다. 2015년에 처음 발표되었으며, 모질라Asm.js구글 네이티브 클라이언트 기술을 기반으로 개발되었다. 웹어셈블리는 웹 표준으로 채택되었으며, 웹 브라우저뿐만 아니라 독립 실행 환경에서도 활용된다. 웹어셈블리는 C/C++, Rust 등 다양한 언어에서 컴파일할 수 있으며, 샌드박스 환경에서 실행되어 보안성을 제공하지만, DOM 조작의 제한, 디버깅 도구 부족 등의 한계도 존재한다.

웹어셈블리 - [IT 관련 정보]에 관한 문서
개요

이미지 준비중입니다.

WebAssembly 로고
유형어셈블리어, 바이트코드
설계자W3C
개발자W3C
Mozilla
Microsoft
Google
Apple
출시일2017년 3월
영향 받은 언어asm.js
PNaCl
Lisp
파일 확장자.wat (텍스트 형식)
.wasm (바이너리 형식)
특징
패러다임구조적
스택 머신
타이핑정적
플랫폼플랫폼 독립
라이선스Apache License 2.0
세부 사항
설명웹 브라우저에서 실행되도록 설계된 크로스 플랫폼 어셈블리어 및 바이트코드이다.
목표웹에서 고성능 애플리케이션을 활성화하는 것이 주요 목표이지만 웹 전용 가정을 하거나 웹 전용 기능을 제공하지 않으므로 다른 환경에서도 사용할 수 있다.
추가 정보이 사양은 웹과 같은 특정 임베딩 환경에 대한 인터페이스를 정의하는 추가 문서로 보완된다.
이러한 문서는 주어진 환경에 적합한 WebAssembly 응용 프로그래밍 인터페이스 (API)를 정의한다.
구조WebAssembly 코드는 '구조화된 스택 머신'으로 간주될 수 있다.
📚 더 읽어볼만한 페이지
  • 어셈블리어 - 기계어
    기계어는 컴퓨터 CPU가 직접 이해하고 실행하는 이진수 형태의 명령어 집합으로, 각 프로세서는 고유한 명령어 집합을 가지며 어셈블리 언어를 통해 니모닉 코드로 표현될 수 있다.
  • 어셈블리어 - 주소 지정 방식
  • 웹 프로그래밍 - 자바스크립트
    자바스크립트는 웹 페이지에 동적인 기능을 추가하기 위해 개발된 프로그래밍 언어로, 초기에는 라이브스크립트라 불렸으나 자바의 인기에 힘입어 변경되었고, ECMAScript로 표준화되어 웹 브라우저와 Node.js 등 다양한 환경에서 활용되지만, 오라클의 상표권 소유로 논란이 있다.
  • 웹 프로그래밍 - 블레이저 (웹 프레임워크)
    블레이저는 마이크로소프트가 개발한 웹 프레임워크로, .NET을 사용하여 웹 애플리케이션을 구축하며, C#과 Razor 구문을 사용해 컴포넌트를 만들고, 서버 측 및 클라이언트 측 렌더링을 모두 지원한다.
  • W3C 표준 - HTML
    HTML은 웹 페이지 제작을 위한 표준 마크업 언어로서, 팀 버너스리가 제안하고 구현한 후 인터넷 발전과 함께 널리 사용되며, SGML에 기반하여 하이퍼텍스트 기능으로 다양한 콘텐츠를 표현하고 연결하며, W3C와 WHATWG에서 표준화를 진행하고 최신 버전은 HTML Living Standard이다.
  • W3C 표준 - 타임드 텍스트
    타임드 텍스트는 영상이나 오디오 콘텐츠에 시간 정보를 담아 표현되는 텍스트로, 자막이나 캡션 등에 활용되며 TTML, WebVTT 등의 표준이 존재한다.

2. 역사

웹어셈블리(WebAssembly)라는 이름은 어셈블리 언어와 비슷하게 들리도록 의도되었다. 이 이름은 어셈블리 언어와 유사한 프로그래밍을 으로 가져와 웹 사이트 사용자의 컴퓨터에서 사용자의 웹 브라우저를 통해 클라이언트 측에서 실행되도록 하는 것을 의미한다. 이를 달성하기 위해 웹어셈블리는 진정한 어셈블리 언어보다 훨씬 더 하드웨어 독립적이어야 한다.

2.1. 초기 개발 및 발표

웹어셈블리는 2015년에 처음 발표되었으며, 첫 시연은 유니티의 앵그리 봇(Angry Bots)을 모질라 파이어폭스, 구글 크롬, 마이크로소프트 엣지에서 실행하는 것이었다. 선도자격 기술은 모질라Asm.js구글 네이티브 클라이언트이었으며, 최초 구현체는 asm.js의 기능 집합에 기반을 두었다.

2.2. 웹 표준화 및 발전

웹어셈블리는 2017년 3월에 최소 기능 제품(MVP) 설계가 완료되었고, 주요 웹 브라우저들이 웹어셈블리를 지원하기 시작했다. 2019년 12월 5일, W3C 권고 "[https://www.w3.org/TR/wasm-core-1/ WebAssembly Core Specification]"이 제정되어 웹어셈블리는 정식 웹 표준으로 인정받았다.

2019년 6월에는 크롬 75가 웹어셈블리 스레드를 기본적으로 활성화하여 출시되었다.

2022년 8월부터 웹어셈블리 2.0이 드래프트 상태가 되었고, SIMD 관련 다수의 명령어와 v128 데이터형, 함수가 다중 값을 반환할 수 있는 기능, 대량의 메모리 초기화·복사 등이 추가되었다.

2023년 10월부터 12월에 걸쳐 Wasm 런타임 측에서 가비지 컬렉션(GC)에 대응하는 WebAssembly Garbage Collection (WasmGC)이 크롬, 파이어폭스, 엣지의 최신 버전에서 기본적으로 활성화되었다.

3. 특징

웹어셈블리(Wasm)는 처음에는 웹 브라우저에서 네이티브에 가까운 코드 실행 속도를 실현하기 위해 설계되었지만, 현재는 웹 브라우저의 틀을 넘어 더 일반적인 맥락과 용도로도 가치가 있다고 여겨진다.

Wasm 자체는 명령어 집합 등의 측면만 정할 뿐, 리눅스 커널이 제공하는 시스템 콜(예: 파일 I/O)이나 웹 브라우저가 제공하는 DOM 접근 등은 제공하지 않는다. 이러한 특징은 안전성과 이식성을 보장한다. 응용에 필요한 API는 별도로 정의되며, Wasm 런타임이 이를 구현함으로써 해당 기능을 제공한다. 이로 인해 Wasm 생태계는 높은 확장성을 갖는다.

웹어셈블리는 이식 가능한 스택 머신이며, 기존 웹 브라우저에서 널리 사용되는 자바스크립트에 비해 구문 분석 및 실행이 더 빠르도록 설계되었다.

3.1. 성능

웹어셈블리(WebAssembly, Wasm)는 자바스크립트보다 빠르고 효율적인 실행을 목표로 설계되었다. 컴팩트한 바이너리 형식으로 인해 로딩 시간이 단축되고, 실행 속도가 향상된다. Wasm은 Compact, Modular, Efficient, Streamable, Parallelizable, Portable을 설계 방침으로 한다.

초기 벤치마크에서는 코드 실행 속도가 로드/인스턴스화 시간을 제외하고 약 91%(10% 느림)였지만, 최근에는 네이티브 속도의 100%에서 33% 사이, 자바스크립트의 120%(20% 빠름)로 나타났다. 2024년 개인 웹 페이지의 브라우저 벤치마크에서는 모바일 폰에서 간단한 게임 애플리케이션 실행 시 네이티브 속도의 110%에서 190% 사이의 결과를 보였다.

2021년 연구에 따르면, 특정 경우와 브라우저에서 웹 어셈블리는 자바스크립트보다 훨씬 빠르다. 예를 들어 작은 파일에서 복잡한 함수를 실행하는 경우(그래픽 파일 처리 등)에 웹 어셈블리가 유리하다. 반면 자바스크립트에는 웹 어셈블리에 없는 JIT와 같은 몇 가지 최적화 기능이 있다.

웹 어셈블리는 DOM에 직접 접근할 수 없어 성능이 저하되는 문제점이 있었지만, 이는 현재 해결되고 있거나 향후 해결될 수 있다.

Wasm 버전 2.0 (드래프트)에는 128비트 폭의 벡터형(`v128`)과 SIMD 명령어가 추가되었다.

3.2. 이식성

웹어셈블리(Wasm) 코드는 이식 가능한 가상 스택 머신 (VM)에서 실행되도록 설계되었다. 이 VM은 자바스크립트보다 더 빠르게 파싱하고 실행하며, 콤팩트한 코드 표현을 갖도록 설계되었다. Wasm 이진 코드가 예상할 수 있는 외부 기능 (예: 시스템 콜)은 표준에서 규정하지 않는다. 대신, VM이 실행되는 호스트 환경의 모듈을 통해 인터페이스를 제공하는 방식을 제공한다.

Wasm 자체는 명령어 집합 등만 정하며, 리눅스 커널이 제공하는 시스템 콜(예: 파일 I/O)이나 웹 브라우저가 제공하는 DOM 접근 등은 제공하지 않는다. 안전성과 이식성은 이러한 특징에서 기인한다. 응용에 필요한 API는 별도로 정의되며, Wasm 런타임이 이를 구현함으로써 해당 기능을 제공한다. 이로 인해 Wasm 생태계는 높은 확장성을 갖는다.

3.3. 보안

웹어셈블리는 기본적으로 외부와 격리된 샌드박스 환경에서 실행된다. WASM은 계산 결과를 전달하거나 외부 함수를 호출하기 위해 'imports'/'exports' 기능을 제공한다. 대상 객체는 함수, 테이블, 메모리, 전역 변수의 네 종류이다. WASM 외부에서 'exports' 요소에 등록된 대상의 인덱스를 통해 해당 객체에 접근할 수 있다(함수 호출 및 메모리 읽기/쓰기). 또한 WASM 런타임은 'imports' 요소에 등록된 대상의 이름과 형식을 통해 WASM 외부에 존재하는 대상에 대한 접근을 제공한다.

3.4. 개방성

웹어셈블리(Wasm)는 처음에는 웹 브라우저에서 네이티브에 가까운 코드 실행 속도를 실현하기 위해 설계되었지만, 현재는 웹 브라우저의 틀을 넘어 더 일반적인 맥락과 용도로도 가치가 있다고 여겨지고 있다.

Wasm 자체는 명령어 집합 등의 측면만 정하며, 리눅스 커널이 제공하는 시스템 콜(예: 파일 I/O)이나 웹 브라우저가 제공하는 DOM 접근 등은 제공하지 않는다. 이러한 특징은 안전성과 이식성을 보장한다. 응용에 필요한 API는 별도로 정의되며, Wasm 런타임이 이를 구현함으로써 해당 기능을 제공한다. 이로 인해 Wasm 생태계는 높은 확장성을 갖는다.

3.5. 웹 브라우저

모질라 파이어폭스, 구글 크롬, 마이크로소프트 엣지 등 모든 주요 브라우저에서 웹어셈블리를 지원한다. iOS, 안드로이드 모바일 웹 브라우저에서도 지원한다. 2024년 3월 기준으로, 99%의 브라우저가 웹어셈블리 (버전 1.0)를 지원하며, 이는 이전 기술인 asm.js를 넘어선 수치이다.

3.6. 독립 실행 환경

웹어셈블리는 처음에는 웹 브라우저에서 거의 네이티브 코드 실행 속도를 허용하도록 설계되었지만, 더 일반적인 맥락에서도 그 가치를 인정받고 있다. 웹어셈블리의 런타임 환경(RE)은 호스트 애플리케이션에 포함될 수 있는 저수준의 가상 스택 머신(JVM 또는 플래시 VM과 유사)이기 때문에, Wasmer, Wasmtime 등과 같은 독립 실행 환경(Standalone Runtime)이 만들어졌다. 이러한 독립 실행 환경은 "서버 측" 웹어셈블리 애플리케이션을 호스팅하기 위해 애플리케이션 서버에 포함되거나, 플러그인 기반 소프트웨어 확장 아키텍처를 지원하기 위해 다른 애플리케이션에도 포함된다. 예를 들어, 웹어셈블리 기반 ABI를 지정하여 프록시 서버를 확장하는 "프록시를 위한 웹어셈블리"(proxy-wasm)가 있다.

3.7. WASI (WebAssembly System Interface)

WASI(WebAssembly System Interface)는 모질라가 설계한, 모든 플랫폼으로 이식 가능하도록 의도된 간단한 인터페이스(ABI 및 API)이다. 이는 POSIX와 유사한 기능을 제공하며, 예를 들어 "역량 기반 보안에 의해 제약된 파일 I/O"와 같은 것을 제공한다. 이 외에도 몇 가지 ABI/API가 제안되고 있다. WASI는 Capsicum의 CloudABI의 영향을 받았다.

도커의 공동 창업자인 솔로몬 하이클스(Solomon Hykes)는 2019년에 "만약 2008년에 WASM+WASI가 존재했다면 도커를 만들 필요가 없었을 것이다, 라고 할 정도로 중요한 것이다. 서버 상에서의 WebAssembly는 컴퓨팅의 미래이다"라고 썼다.

3.8. 컴파일러

EmscriptenCC++LLVM을 백엔드로 사용하여 Wasm으로 컴파일한다. Emscripten SDKLLVM이 지원하는 모든 언어(예: C, C++, Rust 등) 소스 코드를 JavaScript 코드와 동일한 샌드박스에서 실행되는 바이너리 파일로 컴파일할 수 있다. Emscripten은 WebGL과 같이 일반적으로 사용되는 몇 가지 환경 인터페이스에 대한 바인딩을 제공한다.

8버전부터 독립형 Clang은 CC++를 Wasm으로 컴파일할 수 있다. 초기 목표는 CC++로부터의 컴파일을 지원하는 것이었지만, Rust, .NET 언어 및 AssemblyScript (TypeScript와 유사)와 같은 다른 소스 프로그래밍 언어에 대한 지원도 등장하고 있다.

C 언어/C++에서 WebAssembly로 컴파일할 때, Emscripten은 프런트엔드에 clang 혹은 그 포크인 fastcomp-clang을, 중간층에 LLVM 혹은 그 포크인 fastcomp을, 백엔드에 binaryen을 사용한다.

GCC asm.js 백엔드는 asm.js 및 WebAssembly에 대응한다.

LLVM은 WebAssembly 백엔드를 가지고 있으며, WebAssembly 바이너리를 직접 출력할 수 있다. 또한, LLD에 의한 WebAssembly 바이너리 링크도 가능하다. LLVM 8.0에서 정식으로 지원한다.

3.9. 백엔드

Binaryen은 웹어셈블리 툴체인 및 최적화 도구이다. 관련 도구는 다음과 같다.

👆
좌우로 밀어서 보기
Binaryen 도구 목록
도구명설명
asm2wasmasm.js에서 웹어셈블리 텍스트로 변환
s2wasmLLVM의 웹어셈블리용 텍스트 어셈블리(*.s)에서 웹어셈블리 텍스트로 변환
mir2wasmRust 언어의 중간 레벨 IR(MIR)에서 웹어셈블리 텍스트로 변환
wasm-as웹어셈블리 텍스트에서 웹어셈블리 바이너리로 변환


WABT (WebAssembly Binary Toolkit)는 웹어셈블리 바이너리 형식과 텍스트 형식 간 변환 도구를 제공한다. 관련 도구는 다음과 같다.

👆
좌우로 밀어서 보기
WABT 도구 목록
도구명설명
wat2wasm웹어셈블리 텍스트에서 웹어셈블리 바이너리로 변환
wasm-link웹어셈블리 바이너리 링커

3.10. 런타임

WASM(웹어셈블리) 코드는 이식 가능한 가상 스택 머신 (VM)에서 실행되도록 설계된 이진 코드(바이트코드)이다. 이 VM은 자바스크립트보다 더 빠르게 파싱하고 실행하며, 콤팩트한 코드 표현을 갖도록 설계되었다. WASM은 컴퓨터의 실행 파일이 아니므로, 그대로 기계어로 실행할 수 없다. 따라서 WASM 파일은 런타임을 통해 해석 및 실행된다. 런타임에는 인터프리터 / JIT 컴파일러 / AOT 컴파일러가 있으며 용도에 맞춰 선택된다.

Wasm 이진 코드가 예상할 수 있는 외부 기능 (예: 시스템 콜)은 표준에서 규정하지 않는다. 대신, VM이 실행되는 호스트 환경의 모듈을 통해 인터페이스를 제공하는 방식을 제공한다.

👆
좌우로 밀어서 보기
WASM 런타임
실행 환경엔진/런타임컴파일러
구글 크롬 & Node.jsV8Liftoff (baseline) + TurboFan (optimizing)
모질라 파이어폭스스파이더몽키rabaldr (baseline) + BaldrMonkey (optimizing, backed by IonMonkey)
wasmtime-Cranelift
Wasmer-pluggable (LLVM, Cranelift)


런타임은 웹 브라우저에 내장 (자바스크립트 실행 환경에서 호출)되거나 독립적인 WASM 네이티브 런타임 (예: CLI에서 $ wasmtime foo.wasm)으로 존재한다.

과거에 존재했던 런타임에는 Cranelift 컴파일러 기반의 Lucet이 있다.

3.11. 개발 환경

WebAssembly Studio는 웹 기반의 웹어셈블리 개발 환경으로, C 언어 및 Rust를 지원하며, 오픈 소스이다.

4. 한계 및 과제

웹어셈블리는 여러 장점을 가지지만, 다음과 같은 한계점과 과제를 안고 있다.

* DOM 접근 제한: 웹어셈블리 코드는 웹 브라우저문서 객체 모델(DOM)에 직접 접근할 수 없다. 따라서 DOM 조작을 위해서는 자바스크립트를 이용해야 한다.
* 디버깅 및 개발 도구 부족: 2023년 10월 개발자 설문 조사에 따르면, 응답자의 절반 정도만이 웹어셈블리의 현재 상태에 만족했다. 많은 개발자들이 WASI, 디버깅 지원, 자바스크립트 및 브라우저 API와의 통합, 빌드 도구 등에서 개선이 필요하다고 지적했다.
* 메모리 관리: 웹어셈블리에서 메모리 집약적인 할당은 특히 모바일 브라우저에서 안정적인 배포를 어렵게 만드는 심각한 제한 사항으로 작용한다. 현재 Chrome on Android에서 Chrome 관련 해결 방법을 사용하지 않거나 iOS의 Safari에서 300MB 이상의 메모리를 할당하는 것은 안정적이지 않다.

4.1. DOM 접근 제한

웹 어셈블리 코드는 웹 브라우저문서 객체 모델(DOM)에 직접 접근하는 것을 허용하지 않는다. 따라서 Wasm 코드는 DOM 조작을 위해 자바스크립트에 위임해야 한다.

4.2. 디버깅 및 개발 도구 부족

2023년 10월 개발자 설문 조사에서, 303명의 참가자 중 절반도 안 되는 수가 웹어셈블리의 상태에 만족했다. 대다수는 WASI, 디버깅 지원, 자바스크립트 및 브라우저 API와의 통합, 빌드 도구의 네 가지 영역에서 개선이 필요하다고 언급했다.

4.3. 메모리 관리

웹 어셈블리에서 메모리 집약적인 할당은 "모바일 브라우저에서 많은 응용 프로그램을 '안정적으로' 배포하는 것을 불가능하게 만드는 심각한 제한 사항"이 있다. 현재 Chrome on Android에서 Chrome 관련 해결 방법을 사용하지 않거나 iOS의 Safari에서 ~300MB 이상의 메모리를 할당하는 것은 안정적이지 않다.

5. 보안 고려 사항

2018년 6월, 한 보안 연구원은 공유 메모리를 가진 스레드 지원이 추가되면 웹어셈블리를 사용하여 스펙터 및 멜트다운 보안 취약점에 대한 브라우저 완화를 우회할 가능성이 있다고 제시했다. 이러한 우려로 인해 웹어셈블리 개발자들은 해당 기능을 보류했다. 그러나 구글 크롬은 이러한 미래의 언어 확장을 탐구하기 위해 2018년 10월에 웹어셈블리 스레드 제안에 대한 실험적 지원을 추가했다.

웹어셈블리는 구조화된 제어 흐름만 지원하므로 기호 실행을 포함한 보안 검증 기술에 적합하다.

5.1. 악성 코드 은닉

웹어셈블리는 악성 소프트웨어 제작자, 사기꾼, 피싱 공격자가 증거를 은폐하기 쉽게 만든다는 비판을 받았다. 웹어셈블리는 사용자의 기기에 컴파일된 형태로만 존재하여 "악성 소프트웨어 탐지를 어렵게" 만든다. 웹어셈블리의 속도와 은폐 용이성은 웹사이트 방문자의 장치 내에서 숨겨진 암호화폐 채굴에 사용되게 했다. 현재는 운영되지 않는, 웹사이트 방문자의 브라우저에서 암호화폐 채굴을 쉽게 하는 서비스인 코인하이브(Coinhive)는 자사의 "마이너가 웹어셈블리를 사용하며 네이티브 마이너의 약 65% 성능으로 실행된다"고 주장했다. 2019년 6월 브라운슈바이크 공과대학교(Technische Universität Braunschweig)의 연구에 따르면, 알렉사 상위 100만 개의 웹사이트에서 웹어셈블리의 사용을 분석한 결과 악성 암호화폐 채굴에 주로 사용되었으며, 연구 대상 웹어셈블리 사용 웹사이트의 절반 이상이 악성 소프트웨어에 해당했다. 2021년 4월 슈투트가르트 대학교(Universität Stuttgart)의 연구에 따르면, 그 이후 암호화폐 채굴은 주변화되어 광범위한 소스에서 수집된 모든 웹어셈블리 모듈의 1% 미만으로 떨어졌으며, 여기에는 알렉사 상위 100만 개의 웹사이트도 포함된다.

6. 활용 사례

웹어셈블리는 현재 다양한 분야에서 활용되고 있으며, 앞으로 그 활용 범위가 더욱 넓어질 것으로 예상된다.