1. 소개
이 문서는 WebAssembly 명세 [WEBASSEMBLY]와 WebAssembly JavaScript 임베딩 [WASMJS]를 기반으로 작성되었습니다. 이 문서는 WebAssembly가 JavaScript [ECMASCRIPT] 자체의 범위를 벗어나지만, 웹 사용자 에이전트에 의해 구현되는 추가 API와 같이 WebAssembly를 더 넓은 웹 플랫폼과 통합하는 방법을 설명합니다.2. 스트리밍 모듈 컴파일 및 인스턴스화
[Exposed =(Window ,Worker )]partial namespace WebAssembly {Promise <Module >compileStreaming (Promise <Response >,source optional WebAssemblyCompileOptions = {});options Promise <WebAssemblyInstantiatedSource >instantiateStreaming (Promise <Response >,source optional object ,importObject optional WebAssemblyCompileOptions = {}); };options
compileStreaming(source, options)
메서드는 호출되면 source와 options를 사용하여 잠재적 WebAssembly 응답 컴파일의 결과를 반환합니다.
instantiateStreaming(source, importObject, options)
메서드는 호출되면 다음 단계를 수행합니다:
-
promiseOfModule을 source와 options를 이용한 잠재적 WebAssembly 응답 컴파일의 결과로 둔다.
-
importObject로 가져오기(import)를 하여 promiseOfModule의 모듈의 프로미스를 인스턴스화한 결과를 반환한다.
Response
source와 WebAssemblyCompileOptions
options 프로미스와 함께 다음 단계를 수행합니다:
참고: 이 알고리즘은 Response
객체 또는 그에 대한 프로미스를 받아, response의 바이트를 컴파일·인스턴스화합니다. 이 컴파일은 백그라운드에서 스트리밍 방식으로 수행될 수 있습니다.
Response
가
CORS-동일-출처가 아니거나, ok 상태가 아니거나,
`application/wasm` MIME 타입이 아니면, 반환된 프로미스는 TypeError로
거부됩니다;
만약 컴파일 또는 인스턴스화에 실패하면, 반환된 프로미스는 CompileError
또는 원인에 따른 오류로 거부됩니다.
-
returnValue를 새로운 프로미스로 둔다.
-
프로미스 처리 후 반응을 source에 대해 시행한다:
-
source가 unwrappedSource로 이행되었을 때:
-
response를 unwrappedSource의 response로 둔다.
-
mimeType을 response의 헤더 목록에서 Content-Type 가져오기 결과로 둔다.
-
mimeType이 null이면
TypeError로 returnValue를 거부하고, 이 단계 중단. -
mimeType 시작과 끝에서 HTTP 탭 또는 공백 바이트를 모두 제거한다.
-
mimeType이
`application/wasm`와 바이트-대소문자무관 일치가 아니면,TypeError로 returnValue를 거부하고, 이 단계 중단.참고: 빈
`application/wasm;`를 포함해, 추가 매개변수는 허용되지 않습니다. -
response가 CORS-동일-출처가 아니면,
TypeError로 returnValue를 거부하고, 이 단계 중단. -
response의 상태가 ok 상태가 아니면,
TypeError로 returnValue를 거부하고, 이 단계 중단. -
response의 body를
ArrayBuffer로 소비하고, 그 결과를 bodyPromise로 둔다.참고: 명세의 편의상 응답을 모두 소모한 후 컴파일하는 것으로 지정했지만, 실구현은 스트리밍 방식으로 처리할 수 있음. 결과 차이는 관찰 불가이므로, 단순화된 모델로 명세함.
-
프로미스 처리 후 반응을 bodyPromise에 대해 시행:
-
bodyPromise가 bodyArrayBuffer로 이행되면:
-
stableBytes에 bodyArrayBuffer가 포함하는 바이트의 사본을 저장한다.
-
WebAssembly 모듈 비동기 컴파일을 stableBytes와 네트워킹 태스크 소스, options로 수행하고, 결과로 returnValue를 resolve한다.
-
-
bodyPromise가 reason으로 거부되었으면:
-
returnValue 거부에 reason을 사용한다.
-
-
-
-
source가 reason으로 거부되면:
-
returnValue 거부에 reason을 사용한다.
-
-
-
returnValue를 반환한다.
3. 직렬화
웹 사용자 에이전트는 Module
인터페이스에
[Serializable]
익스텐디드 어트리뷰트를 추가해야 합니다.
직렬화 단계는 value, serialized, forStorage가 주어졌을 때 다음과 같습니다:
-
forStorage가 true이면, "DataCloneError"
DOMException을 throw한다. -
serialized.[[Bytes]]를 value.[[Bytes]]의 서브 직렬화로 설정한다.
-
serialized.[[AgentCluster]]를 현재 Realm이 대응하는 agent cluster로 설정한다.
역직렬화 단계는 serialized, value, targetRealm이 주어졌을 때 다음과 같습니다:
-
bytes를 serialized.[[Bytes]]의 서브 역직렬화로 둔다.
-
value.[[Bytes]]를 bytes로 설정한다.
-
targetRealm이 대응하는 agent cluster가 serialized.[[AgentCluster]]와 다르면, "DataCloneError"
DOMException을 throw한다. -
WebAssembly 모듈 컴파일을 bytes로부터 수행하여 value.[[Module]]에 저장한다.
엔진은 구조적 직렬화(structured serialization) 과정에서 내부적으로 컴파일된 코드를 공유/재사용하려고 시도해야 하지만, CPU 업그레이드나 브라우저 업데이트와 같은 예외적인 경우에는 불가능하며 완전 재컴파일이 필요할 수 있습니다.
참고: 구조적 직렬화의 의미는
Module
이 컴파일된 바이너리 소스를 직렬화하고, 역직렬화 후 타깃 Realm에 재컴파일하는 것과 동일합니다.
위의 엔진 최적화 덕분에 구조적 직렬화는 개발자에게 컴파일된 코드의 캐싱 및 윈도우/워커 간 코드 공유에 대한 명시적 제어권을 제공합니다.
4. 개발자용 표시 규칙
이 섹션은 비규범적입니다.
브라우저, JavaScript 엔진, 오프라인 도구는 JavaScript 산출물과 언어 구조를 나타내는 공통 방법을 가지고 있습니다. 예를 들어, JavaScript 소스 코드 위치는 스택 트레이스나 오류 메시지에 출력되며, 텍스트 파일의 10진수 형식 줄과 열로 자연스럽게 표현됩니다. 함수와 변수의 이름도 소스에서 바로 가져옵니다. 따라서(예를 들어) 구현마다 스택 트레이스 문자열 포맷이 완전히 일치하지 않아도, 위치 정보는 쉽게 읽을 수 있으며 브라우저마다 동일합니다.
WebAssembly 구조체의 일관된 표현을 위해, 다음 규칙이 채택되었습니다.
WebAssembly의 위치는 바이너리 내 특정 명령어를 가리키며, 브라우저나 엔진에서 JavaScript 소스 위치와 유사하게 표시될 수 있습니다. 다음과 같은 형식을 가집니다:
${url}:wasm-function[${funcIndex}]:${pcOffset}
여기서
-
${url}은 가능하다면 모듈과 연관된 URL입니다(아래 참고 참조). -
${funcIndex}는 모듈을 기준으로 한 함수 인덱스입니다. -
${pcOffset}는 명령어의 첫 바이트가 모듈 바이너리에서 가진 오프셋으로, 소문자 16진수 및0x를 접두로 출력됩니다.
주의사항:
-
URL 필드는 문맥에 따라 다르게 해석될 수 있습니다. 브라우저에서 응답 기반 인스턴스화 API를 사용할 경우 해당 URL을 사용해야 합니다.
ArrayBuffer기반 인스턴스화 API를 사용할 경우, API 호출 위치를 표시해야 합니다. 이는eval로 JavaScript를 실행하는 것과 유사하므로, 브라우저가eval호출 위치를 나타내는 기존 방식을 사용할 수 있습니다. 예를 들어, 브라우저가foo.js line 10 > eval또는eval at bar (foo.js:10:3)처럼eval을 표시한다면,foo.js line 10 > WebAssembly.instantiate또는WebAssembly.instantiate at bar (foo.js:10:3)처럼도 표시할 수 있습니다. 오프라인 도구는 파일명을 사용할 수 있습니다. -
모듈 오프셋에 16진수를 사용하는 것은
objdump등 네이티브 도구의 관행(주소를 16진수로 출력)과 일치하며, 이를 JavaScript 줄 번호 등 10진수와 시각적으로 구분합니다. 다른 값은 10진수로 표현합니다.
내보낸 함수 인스턴스의 "name" 프로퍼티는 JS API에 의해 지정되지만,
합성된 함수 이름은 디버거의 콜스택이나 스택 트레이스 문자열 표현 등 다른 문맥에도 표시됩니다.
WebAssembly 모듈에 이름 섹션이 있다면,
다음과 같이 함수 이름을 합성해 표시해야 합니다:
-
함수 이름 하위섹션이 있다면, 표시되는 이름은
${module_name}.${function_name}혹은${function_name}(모듈 이름 유무에 따라)을 써야 합니다. -
없다면, 출력은 맥락에 따라 달라질 수 있습니다:
-
함수 이름이 스택 트레이스의 위치와 함께 나타나는 경우, 함수 인덱스가 이미 위치에 포함되므로(모듈 이름만 있거나 비어있을 수 있음) 사용할 수 있습니다.
-
그 외에는,
${module_name}.wasm-function[${funcIndex}]또는wasm-function[${funcIndex}]를 사용하여 함수 인덱스를 전달해야 합니다.
-
이 문서는 스택 프레임 표현 등 문자열의 완전한 포맷을 지정하지 않으므로, 엔진은 JavaScript용 기존 포맷(이미 사용 중인 코드가 있을 수 있음)을 계속 사용할 수 있습니다. 그럼에도, WebAssembly 프레임은 JavaScript와 형식을 일관성 있게 출력해야 합니다.
5. 미디어 타입 등록
미디어 타입 application/wasm은 IANA 미디어 타입 데이터베이스 [IANA-MEDIA-TYPES]에 다음과 같은 등록 템플릿으로 등록되었습니다:
application/wasm
- 타입 이름(Type Name):
- application
- 서브타입 이름(Subtype Name):
- wasm
- 필수 매개변수(Required Parameters):
- 없음
- 선택적 매개변수(Optional Parameters):
- 없음
- 인코딩 고려사항(Encoding Considerations):
- binary
- 보안 고려사항(Security Considerations):
-
WebAssembly는 안전하고 이식 가능한 저수준 코드 포맷이며, 이에 따른 보안 고려사항은 https://www.w3.org/TR/wasm-core/#security-considerations 에 설명되어 있습니다.
WebAssembly 포맷에는 무결성 또는 프라이버시 보호 기능이 내장되어 있지 않습니다. 필요하다면 HTTPS 등 외부에서 제공해야 합니다.
- 상호운용성 고려사항(Interoperability Considerations):
- WebAssembly Core 적합성 참조
https://www.w3.org/TR/wasm-core/#conformance - 공개 명세(Published specification):
- https://www.w3.org/TR/wasm-core-1/ https://www.w3.org/TR/wasm-js-api-1/ https://www.w3.org/TR/wasm-web-api-1/
- 적용 용도(Application Usage):
- application/wasm 미디어 타입은 HTTP를 통해 브라우저에서 실행되도록 WebAssembly 파일을 전송할 때 사용하도록 고안되었습니다. 이는 매우 일반적인 시나리오입니다. 또한 이 타입은 여러 WebAssembly 런타임에서 안전성 및 이식성을 활용하며, 효율적인 실행과 압축된 표현을 목표로 사용됩니다.
- 프래그먼트 식별자 고려(Fragment Identifier Considerations):
- 없음
- 사용 제한(Restrictions on usage):
- 없음
- 임시 등록(Provisional Registrations):
- N/A
- 추가 정보(Additional information):
-
- 이 타입의 사용 중단된 별칭명들:
- 없음
- 매직 넘버(Magic number(s)):
- 0x00 0x61 0x73 0x6D
- 파일 확장자(File extension(s)):
- .wasm
- 맥킨토시 파일 타입 코드(Macintosh file type code(s)):
- 없음
- 객체 식별자(Object Identifier(s) or OID(s)):
- 없음
- 의도된 사용(Intended usage):
- 일반(Common)
- 기타 정보 및 의견(Other Information & Comments):
- 일반(Common)
- 담당자(Contact Person):
-
- 담당자 이름(Contact Name):
- Eric Prud’hommeaux
- 담당자 이메일(Contact Email Address):
- eric@w3.org
- 작성자/변경 관리자(Author/Change Controller):
- W3C
6. 보안 및 개인정보 보호 고려사항
이 섹션은 비규범적입니다.
WebAssembly는 JS API 명세에 설명된 JavaScript API를 통해서만 주변 환경에 접근할 수 있습니다. 따라서 WebAssembly는 JavaScript로 수집, 노출, 처리할 수 있는 것 외에는 웹사이트나 타사에 어떠한 정보(개인정보, 민감 정보 등)를 수집하거나 노출할 수 없습니다. WebAssembly 메모리는 주변 JavaScript 환경 내 객체와 동일한 수명을 가지며, (JavaScript로 추출하여 기존 직렬화 API를 사용하는 경우를 제외하고) 영구 저장되거나 직렬화되지 않습니다. 기본 플랫폼이나 하드웨어, 다른 장치, 사용자 에이전트의 네이티브 UI 등에 접근 권한도 제공되지 않습니다.WebAssembly는 추가적인 프로그램 실행 메커니즘으로, JavaScript가 실행될 수 있는 곳 어디서든 실행될 수 있습니다. 따라서 위협 모델은 본질적으로 JavaScript 코드와 동일하며, 전달(예: WebAssembly 코드는 적극적·수동적 네트워크 공격자로부터 전송 중 보호되어야 함) 및 정책(예: 일부 로딩 방식 또는 실행은 동일 출처 정책이나 Content Security Policy와 같은 메커니즘으로 제한됨)에 대한 고려도 비슷합니다.
7. 변경 이력
이 섹션은 비규범적입니다.
WebAssembly 명세 1.0 최초 릴리스 이후 여러 확장 제안이 통합되었습니다. 다음 섹션에서는 변경된 내용을 개략적으로 제공합니다.
7.1. 2.0 릴리스
미디어 타입 등록 완료
application/wasm 미디어 타입에 대한 등록이 성공적으로 완료되었습니다.