WebAssembly JavaScript 인터페이스

W3C 후보 권고안 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/CRD-wasm-js-api-2-20261027/
최신 게시 버전:
https://www.w3.org/TR/wasm-js-api-2/
에디터 초안:
https://webassembly.github.io/spec/js-api/
히스토리:
https://www.w3.org/standards/history/wasm-js-api-2/
구현 보고서:
https://webassembly.org/features/
피드백:
GitHub
사양 내 인라인
에디터:
Ms2ger (Igalia)
Ryan Hunt (Mozilla Foundation)
이슈 추적:
GitHub Issues

초록

이 문서는 WebAssembly와 상호 작용하기 위한 명시적인 JavaScript API를 제공한다.

이것은 관련 문서 모음의 일부이다: Core WebAssembly Specification, WebAssembly JS Interface, 그리고 WebAssembly Web API.

이 문서의 상태

이 절에서는 이 문서가 출판되었을 당시의 상태를 설명한다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정판은 W3C 기술 보고서 색인에서 찾을 수 있다.

이 문서는 WebAssembly Working Group에 의해 Recommendation track을 사용한 Candidate Recommendation Draft로 출판되었다.

Candidate Recommendation으로의 출판은 W3C 및 그 구성원의 승인을 의미하지 않는다. Candidate Recommendation Draft는 작업 그룹이 이후의 Candidate Recommendation Snapshot에 포함하려는 이전 Candidate Recommendation의 변경 사항을 통합한다.

WebAssembly Working group은 이 출판물을 Candidate Recommendation 상태로 유지하고, Recommendation 상태로 전환하기보다는 "living standard"로서 지속적으로 갱신할 의도가 있다.

이 문서는 언제든지 유지되고 갱신된다. 이 문서의 일부는 작업 진행 중이다.

GitHub Issues 는 이 명세를 논의하기 위해 선호된다. 모든 이슈와 댓글은 보관된다.

이 문서는 WebAssembly Working Group에 의해 작성되었다.

이 문서는 W3C Patent Policy에 따라 운영되는 그룹에 의해 작성되었다. W3C는 공개 목록을 유지하며 모든 특허 공개 는 그룹의 산출물과 관련하여 이루어진 것이다; 해당 페이지에는 특허를 공개하는 방법에 대한 지침도 포함되어 있다. 어떤 개인이 자신이 실제로 알고 있는 특허가 Essential Claim(s) 을 포함한다고 믿는 경우, 그 정보는 W3C Patent Policy의 6절에 따라 공개해야 한다.

이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받는다.

1. 서론

설계상 WebAssembly 코어 명세 [WEBASSEMBLY]의 범위에는 WebAssembly 프로그램이 자신을 둘러싼 실행 환경과 어떻게 상호 작용하는지에 대한 설명이 포함되지 않는다. 대신 이 명세는 WebAssembly와 그 환경 사이의 추상적인 임베딩 인터페이스를 정의하며, (이를 embedder라고 부른다). 임베더는 오직 이 인터페이스를 통해서만 WebAssembly의 의미론과 상호 작용하며, 임베더는 자신의 호스트 환경과 임베딩 API 사이의 연결을 구현한다. 이 문서는 WebAssembly를 JavaScript [ECMASCRIPT] 환경에 임베딩하는 방식을 설명하며, 여기에는 WebAssembly 모듈을 어떻게 구성하고 인스턴스화하는지, 가져오기 및 내보내기 함수가 어떻게 호출되는지, 데이터가 어떻게 교환되는지, 그리고 오류가 어떻게 처리되는지가 포함된다. JavaScript 환경 자체가 웹 브라우저에 임베딩되어 있을 때는 웹 API 명세 [WASMWEB]가 웹 환경과 관련된 추가 동작을 설명한다.

2. API 사용 예시

이 절은 비규범적이다.

demo.wat이 주어졌다고 하자 (demo.wasm으로 인코딩됨):

(module
    (import "js" "import1" (func $i1))
    (import "js" "import2" (func $i2))
    (func $main (call $i1))
    (start $main)
    (func (export "f") (call $i2))
)

그리고 브라우저에서 실행되는 다음 JavaScript:

var importObj = {js: {
    import1: () => console.log("hello,"),
    import2: () => console.log("world!")
}};
fetch('demo.wasm').then(response =>
    response.arrayBuffer()
).then(buffer =>
    WebAssembly.instantiate(buffer, importObj)
).then(({module, instance}) =>
    instance.exports.f()
);

3. 표기법

이 명세는 Infra Standard에 의존한다. [INFRA]

WebAssembly의 sequence 타입은 그곳에 정의된 list 타입과 동등하다; 한쪽의 값은 다른 쪽의 값으로 투명하게 취급된다.

4. 내부 저장소

4.1. WebAssembly 저장소와 JavaScript의 상호 작용

참고: WebAssembly 의미론은 WebAssembly 추상 기계의 상태를 나타내는 추상적인 저장소를 기준으로 정의된다. WebAssembly 연산은 저장소를 받아 갱신된 저장소를 반환한다.

각 agent는 연관 저장소를 가진다. 새 agent가 생성되면, 그 연관 저장소는 store_init()의 결과로 설정된다.

참고: 이 명세에서는 WebAssembly 관련 객체, 메모리 또는 주소를 agent cluster 내의 agent들 사이에서 공유할 수 없다. 향후 버전의 WebAssembly에서는 이것이 바뀔 수 있다.

WebAssembly 저장소의 요소는 JavaScript 값과 식별될 수 있다. 특히, 대응하는 Memory 객체를 가진 각 WebAssembly 메모리 인스턴스는 JavaScript Data Block과 식별된다; 이 Data Block에 대한 수정은 그 변경을 반영하는 저장소로 agent의 저장소를 갱신하는 것과 식별되며, 그 반대도 마찬가지이다.

4.2. WebAssembly JS 객체 캐시

참고: 대응하는 JavaScript 객체를 가질 수 있는 WebAssembly 객체가 여러 가지 있다. 이 대응 관계는 agent별로 WebAssembly 주소에서 JavaScript 객체로의 매핑에 저장된다. 이 매핑은 주어진 agent에 대해 특정 WebAssembly 주소에 대응하는 JavaScript 객체가 최대 하나만 존재하도록 보장하는 데 사용된다. 그러나 이 속성은 공유 객체에는 적용되지 않는다.

각 agent는 다음 순서 있는 맵들과 연관된다:

5. WebAssembly 네임스페이스

dictionary WebAssemblyInstantiatedSource {
    required Module module;
    required Instance instance;
};

dictionary WebAssemblyCompileOptions {
    USVString? importedStringConstants = null;
    sequence<USVString> builtins = [];
};

[Exposed=*]
namespace WebAssembly {
    boolean validate([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});
    Promise<Module> compile([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});

    Promise<WebAssemblyInstantiatedSource> instantiate(
        [AllowResizable] AllowSharedBufferSource bytes, optional object importObject, optional WebAssemblyCompileOptions options = {});

    Promise<Instance> instantiate(
        Module moduleObject, optional object importObject);

    readonly attribute Tag JSTag;
};
WebAssembly 모듈을 컴파일하기 위해 소스 바이트 bytes로부터 다음 단계를 수행한다:
  1. module을 module_decode(bytes)라고 하자. 만약 module이 error이면, error를 반환한다.

  2. 만약 module_validate(module)가 error이면, error를 반환한다.

  3. module을 반환한다.

다음과 같이 WebAssembly 모듈의 내장 기능 및 가져온 문자열을 검증합니다. 모듈 module, 활성화된 내장 기능 builtinSetNames 및 importedStringModule이 주어지면 다음 단계를 수행합니다:

  1. 만약 내장 기능 집합 이름 검증을 builtinSetNames에 대해 수행한 결과가 false이면 false를 반환합니다.

  2. 각각에 대해 import를 module_imports(module)에서 가져와 다음을 수행합니다.

    1. importedStringModule이 null이 아니고 import[0]이 importedStringModule과 같으면,

      1. importExternType을 import[2]로 설정합니다.

      2. stringExternType을 global ref extern으로 설정합니다.

      3. match_externtype(stringExternType, importExternType)가 false이면 false를 반환합니다

    2. 그렇지 않으면,

      1. 가져오기의 내장 기능 검증을 import와 builtinSetNames로 수행한 결과가 false이면, false를 반환합니다.

  3. true를 반환합니다.

validate(bytes, options) 메서드는 호출되면 다음 단계를 수행한다:
  1. stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.

  2. stableBytes를 WebAssembly 모듈로 컴파일하고 그 결과를 module로 저장한다.

  3. 만약 module이 error이면, false를 반환한다.

  4. builtinSetNames를 options["builtins"]라고 하자.

  5. importedStringModule을 options["importedStringConstants"]라고 하자.

  6. 만약 빌트인 및 imported strings 검증을 module에 대해 builtinSetNames 및 importedStringModule와 함께 수행한 결과가 false이면, false를 반환한다.

  7. true를 반환한다.

Module 객체는 하나의 WebAssembly 모듈을 나타낸다. 각 Module 객체는 다음 내부 슬롯을 가진다:

모듈 module, 소스 바이트 bytes, 활성화된 빌트인 builtinSetNames, 그리고 importedStringModule로부터 WebAssembly 모듈 객체를 구성하기 위해 다음 단계를 수행한다:
  1. moduleObject를 새로운 Module이라고 하자.

  2. moduleObject.[[Module]]를 module로 설정한다.

  3. moduleObject.[[Bytes]]를 bytes로 설정한다.

  4. moduleObject.[[BuiltinSets]]를 builtinSetNames로 설정한다.

  5. moduleObject.[[ImportedStringModule]]를 importedStringModule로 설정한다.

  6. moduleObject를 반환한다.

소스 바이트 bytes와 WebAssemblyCompileOptions options로부터 선택적 task source taskSource를 사용하여 WebAssembly 모듈을 비동기적으로 컴파일하기 위해 다음 단계를 수행한다:
  1. promise를 새로운 promise라고 하자.

  2. 다음 단계를 병렬로 실행한다:

    1. WebAssembly 모듈을 컴파일합니다 bytes를 컴파일하고 그 결과를 module로 저장합니다.

    2. 태스크를 큐에 넣습니다. taskSource가 제공된 경우, 다음 단계를 수행하도록 해당 taskSource에 태스크를 큐에 넣습니다:

      1. module이 오류인 경우, 거부합니다 promise를 CompileError 예외로 거부하고 반환합니다.

      2. builtinSetNames를 options["builtins"]로 둡니다.

      3. importedStringModule을 options["importedStringConstants"]로 둡니다.

      4. module에 대해 builtinSetNames 및 importedStringModule을 사용하여 내장 기능과 가져온 문자열을 검증한 결과가 false이면, 거부합니다 promise를 CompileError 예외로 거부합니다.

      5. 그렇지 않으면,

        1. module, bytes, builtinSetNames, importedStringModule로부터 WebAssembly 모듈 객체를 생성하고, 그 결과를 moduleObject로 둡니다.

        2. moduleObject를 사용하여 promise를 해결합니다.

  3. promise를 반환한다.

compile(bytes, options) 메서드는 호출되면 다음 단계를 수행한다:
  1. stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.

  2. stableBytes로부터 WebAssembly 모듈을 비동기적으로 컴파일하고 options를 사용하여 그 결과를 반환한다.

가져온 문자열을 인스턴스화하려면 모듈 module 및 importedStringModule을 사용하여 다음 단계를 수행합니다:

  1. 단언: importedStringModule은 null이 아닙니다.

  2. exportsObject를 OrdinaryObjectCreate(null)로 둡니다.

  3. 각각에 대해 module_imports(module)의 (moduleName, componentName, externtype)에 대해,

    1. moduleName이 importedStringModule과 같지 않으면 계속합니다.

    2. stringConstant를 componentName으로 둡니다.

    3. status를 ! CreateDataProperty(exportsObject, stringConstant, stringConstant)로 둡니다.

    4. 단언: status는 true입니다.

  4. exportsObject를 반환합니다.

WebAssembly 모듈 module과 가져오기 객체 importObject, 활성화된 내장 기능 builtinSetNames 및 importedStringModule로부터 가져오기를 읽으려면 다음 단계를 수행합니다.
  1. module_imports(module)가 비어 있지 않고, importObject가 제공되지 않았다면 TypeError 예외를 던집니다.

  2. builtinOrStringImports를 순서가 있는 맵 «[ ]»으로 둡니다.

  3. builtinSetNames의 각 builtinSetName에 대해 다음을 수행합니다.

    1. builtinSetQualifiedName을 builtinSetName 앞에 "wasm:"을 붙인 값으로 둡니다.

    2. 단언: builtinOrStringImports는 builtinSetQualifiedName을 포함하지 않습니다.

    3. builtinSetName이 내장 기능 집합을 참조하지 않으면 계속 진행합니다.

    4. exportsObject를 builtinSetName으로 내장 기능 집합을 인스턴스화한 결과로 둡니다.

    5. 설정합니다: builtinOrStringImports[builtinSetQualifiedName]을 exportsObject로 설정합니다.

  4. importedStringModule이 null이 아니면,

    1. exportsObject를 가져온 문자열을 인스턴스화한 결과로 두며, module과 importedStringModule을 사용합니다.

    2. 설정합니다: builtinOrStringImports[importedStringModule]을 exportsObject로 설정합니다.

  5. imports를 « »로 둡니다.

  6. 각 (moduleName, componentName, externtype)에 대해 module_imports(module)에서 다음을 수행합니다.

    1. builtinOrStringImports[moduleName]이 존재하면,

      1. o를 builtinOrStringImports[moduleName]로 둡니다.

      2. o가 Object가 아니거나 ? HasProperty(o, componentName)가 false이면,

        1. o를 ? Get(importObject, moduleName)으로 설정합니다.

    2. 그렇지 않으면,

      1. o를 ? Get(importObject, moduleName)으로 둡니다.

    3. o가 Object가 아니면, TypeError 예외를 던집니다.

    4. v를 ? Get(o, componentName)으로 둡니다.

    5. externtype이 func functype 형식이면,

      1. IsCallable(v)이 false이면, LinkError 예외를 던집니다.

      2. v에 [[FunctionAddress]] 내부 슬롯이 있어 내보낸 함수에 해당하면,

        1. funcaddr를 v의 [[FunctionAddress]] 내부 슬롯 값으로 둡니다.

      3. 그렇지 않으면,

        1. v와 functype으로 호스트 함수를 생성하고, funcaddr를 그 결과로 둡니다.

        2. index를 imports에 있는 외부 함수의 수로 둡니다. 이 값 index를 호스트 함수의 인덱스라고 하며, funcaddr에 해당합니다.

      4. externfunc를 외부 값 func funcaddr로 둡니다.

      5. 추가합니다: externfunc를 imports에 추가합니다.

    6. externtype이 global mut valtype 형식이면,

      1. v가 Global을 구현하면,

        1. globaladdr를 v.[[Global]]로 둡니다.

      2. 그렇지 않으면,

        1. valtype이 i64이고 v가 BigInt가 아니면,

          1. LinkError 예외를 던집니다.

        2. valtype이 i32, f32 또는 f64 중 하나이고 v가 Number가 아니면,

          1. LinkError 예외를 던집니다.

        3. valtype이 v128이면,

          1. LinkError 예외를 던집니다.

        4. value를 ToWebAssemblyValue(v, valtype)로 둡니다. 이 연산이 TypeError를 던지면, 이를 포착한 후 LinkError 예외를 던집니다.

        5. store를 주변 에이전트의 연결된 저장소로 둡니다.

        6. (store, globaladdr)를 global_alloc(store, valtype, value)으로 둡니다.

        7. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

      3. externglobal을 global globaladdr로 둡니다.

      4. 추가합니다: externglobal을 imports에 추가합니다.

    7. externtype이 mem memtype 형식이면,

      1. v가 Memory를 구현하지 않으면, LinkError 예외를 던집니다.

      2. externmem을 외부 값 mem v.[[Memory]]로 둡니다.

      3. 추가합니다: externmem을 imports에 추가합니다.

    8. externtype이 table tabletype 형식이면,

      1. v가 Table을 구현하지 않으면, LinkError 예외를 던집니다.

      2. tableaddr를 v.[[Table]]로 둡니다.

      3. externtable을 외부 값 table tableaddr로 둡니다.

      4. 추가합니다: externtable을 imports에 추가합니다.

    9. externtype이 tag functype 형식이면,

      1. v가 Tag를 구현하지 않으면, LinkError 예외를 던집니다.

      2. tagaddr를 v.[[Address]]로 둡니다.

      3. externtag를 외부 값 tag tagaddr로 둡니다.

      4. 추가합니다: externtag를 imports에 추가합니다.

  7. imports를 반환합니다.

참고: 이 알고리즘은 올바른 종류의 JavaScript 값이 전달되었는지만 확인합니다. WebAssembly 타입 요구 사항의 검증은 "WebAssembly 모듈의 핵심을 인스턴스화"하는 알고리즘으로 연기됩니다.

WebAssembly 모듈 module과 인스턴스 instance로부터 내보내기 객체를 생성하려면 다음 단계를 수행합니다.
  1. exportsObject를 OrdinaryObjectCreate(null)로 둡니다.

  2. 각 (name, externtype)에 대해 module_exports(module)에서 다음을 수행합니다.

    1. externval을 instance_export(instance, name)으로 둡니다.

    2. 단언: externval은 오류가 아닙니다.

    3. externtype이 func functype 형식이면,

      1. 단언: externval은 func funcaddr 형식입니다.

      2. func funcaddr를 externval로 둡니다.

      3. func를 funcaddr로부터 새로운 내보낸 함수를 생성한 결과로 둡니다.

      4. value를 func로 둡니다.

    4. externtype이 global mut globaltype 형식이면,

      1. 단언: externval은 global globaladdr 형식입니다.

      2. global globaladdr를 externval로 둡니다.

      3. global을 새로운 Global 객체를 globaladdr로부터 생성한 결과로 둡니다.

      4. value를 global로 둡니다.

    5. externtype이 mem memtype 형식이면,

      1. 단언: externval은 mem memaddr 형식입니다.

      2. mem memaddr를 externval로 둡니다.

      3. memory를 새로운 Memory 객체를 memaddr로부터 생성한 결과로 둡니다.

      4. value를 memory로 둡니다.

    6. externtype이 table tabletype 형식이면,

      1. 단언: externval은 table tableaddr 형식입니다.

      2. table tableaddr를 externval로 둡니다.

      3. table을 새로운 Table 객체를 tableaddr로부터 생성한 결과로 둡니다.

      4. value를 table로 둡니다.

    7. externtype이 tag functype 형식이면,

      1. 단언: externval은 tag tagaddr 형식입니다.

      2. tag tagaddr를 externval로 둡니다.

      3. tag를 새로운 Tag 객체를 tagaddr로부터 생성한 결과로 둡니다.

      4. value를 tag로 둡니다.

    8. status를 ! CreateDataProperty(exportsObject, name, value)로 둡니다.

    9. 단언: status는 true입니다.

    참고: WebAssembly 모듈 검증 중 수행되는 유효성 및 고유성 검사는 각 속성 이름이 유효하고 동일한 속성이 두 번 정의되지 않도록 보장합니다.

  3. ! SetIntegrityLevel(exportsObject, "frozen")을 수행합니다.

  4. exportsObject를 반환합니다.

WebAssembly 모듈 module 및 인스턴스 instance에서 instanceObject 인스턴스 객체를 초기화하려면, 다음 단계를 수행합니다:
  1. module 및 instance에서 내보내기 객체를 생성하고 그 결과를 exportsObject로 둡니다.

  2. instanceObject.[[Instance]]를 instance로 설정합니다.

  3. instanceObject.[[Exports]]를 exportsObject로 설정합니다.

모듈 module 및 가져오기 imports에서 WebAssembly 모듈의 코어를 인스턴스화하려면 다음 단계를 수행합니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. (store, result)를 module_instantiate(store, module, imports)로 둡니다.

  3. result가 오류이면 적절한 예외 유형을 발생시킵니다:

    • 링크 중 발생하는 대부분의 경우에는 LinkError 예외를 발생시킵니다.

    • 시작 함수를 실행할 때 오류가 발생했다면 WebAssembly에서 발생하는 대부분의 오류에는 RuntimeError를 발생시키거나, 내부 ECMAScript 코드에서 전파된 오류 객체를 발생시킵니다.

    • 적절한 경우, 예를 들어 메모리 부족 예외와 같은 다른 오류 유형을 WebAssembly 오류 매핑에 문서화된 대로 발생시킵니다.

  4. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  5. result를 반환합니다.

WebAssembly 모듈을 비동기적으로 인스턴스화하려면 Module moduleObject 및 가져오기 importObject로부터 다음 단계를 수행합니다:
  1. promise를 새 프로미스로 둡니다.

  2. module을 moduleObject.[[Module]]로 둡니다.

  3. builtinSetNames를 moduleObject.[[BuiltinSets]]로 둡니다.

  4. importedStringModule을 moduleObject.[[ImportedStringModule]]로 둡니다.

  5. module의 가져오기를 읽되, 가져오기 importObject, builtinSetNames 및 importedStringModule을 사용하고, imports를 그 결과로 둡니다. 이 연산이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 promise를 반환합니다.

  6. 다음 단계를 병렬로 실행합니다:

    1. 다음 단계를 수행하도록 태스크를 큐에 넣습니다: 참고: 여기에서 구현별 작업을 수행할 수 있습니다.

      1. imports를 사용하여 module의 WebAssembly 모듈의 코어를 인스턴스화하고, 그 결과를 instance로 둡니다. 이 작업이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 이 하위 단계를 종료합니다.

      2. instanceObject를 Instance의 새 인스턴스로 둡니다.

      3. module 및 instance로부터 instanceObject를 초기화합니다. 이 작업이 예외를 발생시키면 이를 포착하고, 해당 예외로 거부합니다 promise를 거부하고 이 하위 단계를 종료합니다.

      4. instanceObject로 promise를 해결합니다.

  7. promise를 반환합니다.

가져오기 importObject를 사용하여 promiseOfModule이라는 모듈의 프로미스를 인스턴스화하려면 다음 단계를 수행합니다:
  1. promise를 새 프로미스로 둡니다.

  2. promiseOfModule에 반응합니다:

  3. promise를 반환합니다.

instantiate(bytes, importObject, options) 메서드는 호출되면 다음 단계를 수행합니다:
  1. stableBytes를 bytes 버퍼가 보유한 바이트의 복사본으로 둡니다.

  2. stableBytes로부터 options를 사용하여 WebAssembly 모듈을 비동기적으로 컴파일하고, 그 결과를 promiseOfModule로 둡니다.

  3. 가져오기 importObject를 사용하여 promiseOfModule을 인스턴스화하고 그 결과를 반환합니다.

instantiate(moduleObject, importObject) 메서드는 호출되면 다음 단계를 수행합니다:
  1. importObject를 가져오면서 moduleObject인 WebAssembly 모듈을 비동기적으로 인스턴스화하고, 그 결과를 반환합니다.

참고: 후속 스트리밍 API는 WebAssembly Web API에 문서화되어 있습니다.

WebAssembly Namespace의 JSTag 속성의 getter는 호출되면 다음 단계를 수행합니다:

  1. JSTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.

  2. JSTagObject를 JSTagAddr로부터 Tag 객체를 생성한 결과로 둡니다.

  3. JSTagObject를 반환합니다.

5.1. 모듈

enum ImportExportKind {
  "function",
  "table",
  "memory",
  "global",
  "tag"
};

enum AddressType {
  "i32",
  "i64",
};

typedef any AddressValue;

dictionary ModuleExportDescriptor {
  required USVString name;
  required ImportExportKind kind;
  // Note: Other fields such as signature may be added in the future.
};

dictionary ModuleImportDescriptor {
  required USVString module;
  required USVString name;
  required ImportExportKind kind;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Module {
  constructor([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});
  static sequence<ModuleExportDescriptor> exports(Module moduleObject);
  static sequence<ModuleImportDescriptor> imports(Module moduleObject);
  static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName);
};
외부 타입의 문자열 값 type은 다음과 같습니다.
exports(moduleObject) 메서드는 호출되면, 다음 단계를 수행한다:
  1. module을 moduleObject.[[Module]]라고 하자.

  2. exports를 « »라고 하자.

  3. 각각에 대해 module_exports(module)의 (name, type)에 대해,

    1. kind를 type의 extern type의 문자열 값이라고 하자.

    2. obj를 «[ "name" → name, "kind" → kind ]»라고 하자.

    3. Append를 사용하여 obj를 exports에 추가한다.

  4. exports를 반환한다.

imports(moduleObject) 메서드는 호출되면, 다음 단계를 수행한다:
  1. module을 moduleObject.[[Module]]라고 하자.

  2. builtinSetNames를 moduleObject.[[BuiltinSets]]라고 하자.

  3. importedStringModule를 moduleObject.[[ImportedStringModule]]라고 하자.

  4. imports를 « »라고 하자.

  5. 각각에 대해 module_imports(module)의 (moduleName, name, type)에 대해,

    1. 만약 (moduleName, name, type)에 대해 빌트인을 찾기 결과가 있고 builtinSetNames가 null이 아니면, continue한다.

    2. 만약 importedStringModule이 null이 아니고 moduleName이 importedStringModule과 같다면, continue한다.

    3. kind를 type의 extern type의 문자열 값이라고 하자.

    4. obj를 «[ "module" → moduleName, "name" → name, "kind" → kind ]»라고 하자.

    5. Append를 사용하여 obj를 imports에 추가한다.

  6. imports를 반환한다.

customSections(moduleObject, sectionName) 메서드는 호출되면 다음 단계를 수행한다:
  1. bytes를 moduleObject.[[Bytes]]라고 하자.

  2. customSections를 « »라고 하자.

  3. 각각에 대해 bytes의 custom section customSection에 대해, module grammar에 따라 해석한다,

    1. name을 customSection의 name을 UTF-8로 디코드한 것이라고 하자.

    2. 단언: name은 failure가 아니다 (moduleObject.[[Module]]은 유효하다).

    3. 만약 name이 문자 값으로서 sectionName과 같다면,

      1. Append를 사용하여 새로운 ArrayBuffer를 customSections에 추가한다. 이 ArrayBuffer는 이 customsec 생성 규칙에 매치된 범위에 대한 bytes의 복사본 바이트를 포함한다.

  4. customSections를 반환한다.

Module(bytes, options) 생성자는 호출되면 다음 단계를 수행한다:
  1. stableBytes를 버퍼가 보유한 바이트의 복사본 bytes라고 하자.

  2. stableBytes를 WebAssembly 모듈로 컴파일하고 그 결과를 module로 저장한다.

  3. 만약 module이 error이면, CompileError 예외를 던진다.

  4. builtinSetNames를 options["builtins"]라고 하자.

  5. importedStringModule을 options["importedStringConstants"]라고 하자.

  6. 만약 빌트인 및 imported strings 검증을 module에 대해 builtinSetNames 및 importedStringModule와 함께 수행한 결과가 false이면, CompileError 예외를 던진다.

  7. this.[[Module]]를 module로 설정한다.

  8. this.[[Bytes]]를 stableBytes로 설정한다.

  9. this.[[BuiltinSets]]를 builtinSetNames로 설정한다.

  10. this.[[ImportedStringModule]]를 importedStringModule로 설정한다.

참고: 일부 구현은 bytes에 크기 제한을 적용한다. 이 API의 사용은 비동기 API를 선호하여 권장되지 않는다.

5.2. 인스턴스

[LegacyNamespace=WebAssembly, Exposed=*]
interface Instance {
  constructor(Module module, optional object importObject);
  readonly attribute object exports;
};
Instance(moduleObject, importObject) 생성자는 호출되면 다음 단계를 실행한다:
  1. builtinSetNames를 moduleObject.[[BuiltinSets]]라고 하자.

  2. importedStringModule를 moduleObject.[[ImportedStringModule]]라고 하자.

  3. module을 moduleObject.[[Module]]라고 하자.

  4. module의 imports를 읽고, imports importObject, builtinSetNames, 그리고 importedStringModule와 함께 사용하여, 그 결과를 imports라고 하자.

  5. module을 imports와 함께 WebAssembly 모듈의 코어로 인스턴스화하고, 그 결과를 instance라고 하자.

  6. module과 instance로부터 초기화하여 this를 설정한다.

참고: 이 동기 API의 사용은 권장되지 않는다. 일부 구현에서는 인스턴스화할 때 때때로 오래 걸리는 컴파일 작업을 수행하기 때문이다.

Instance의 exports 속성 getter는 this.[[Exports]]를 반환한다.

5.3. 메모리

dictionary MemoryDescriptor {
  required AddressValue initial;
  AddressValue maximum;
  AddressType address;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Memory {
  constructor(MemoryDescriptor descriptor);
  AddressValue grow(AddressValue delta);
  ArrayBuffer toFixedLengthBuffer();
  ArrayBuffer toResizableBuffer();
  readonly attribute ArrayBuffer buffer;
};

Memory 객체는 여러 Instance 객체가 동시에 참조할 수 있는 단일 메모리 인스턴스를 나타낸다. 각 Memory 객체는 다음 내부 슬롯을 가진다:

메모리 주소 memaddr로부터 고정 길이 메모리 버퍼를 생성하려면, 다음 단계를 수행한다:
  1. block을 memaddr의 기저 메모리와 식별되는 Data Block이라고 하자.

  2. buffer를 내부 슬롯 [[ArrayBufferData]], [[ArrayBufferByteLength]], 그리고 [[ArrayBufferDetachKey]]를 가진 새 ArrayBuffer 라고 하자.

  3. buffer.[[ArrayBufferData]]를 block으로 설정한다.

  4. buffer.[[ArrayBufferByteLength]]를 block의 길이로 설정한다.

  5. buffer.[[ArrayBufferDetachKey]]를 "WebAssembly.Memory"로 설정한다.

  6. buffer를 반환한다.

메모리 주소 memaddr 및 maxsize로부터 크기 조절 가능한 메모리 버퍼를 생성하려면, 다음 단계를 수행한다:
  1. block을 memaddr의 기저 메모리와 식별되는 Data Block이라고 하자.

  2. length를 block의 길이라고 하자.

  3. buffer를 내부 슬롯 [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferMaxByteLength]], 그리고 [[ArrayBufferDetachKey]]를 가진 새 ArrayBuffer 라고 하자.

  4. buffer.[[ArrayBufferData]]를 block으로 설정한다.

  5. buffer.[[ArrayBufferByteLength]]를 length로 설정한다.

  6. buffer.[[ArrayBufferMaxByteLength]]를 maxsize로 설정한다.

  7. buffer.[[ArrayBufferDetachKey]]를 "WebAssembly.Memory"로 설정한다.

  8. buffer를 반환한다.

메모리 주소 memaddr로부터 메모리 객체 memory를 초기화하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Memory 객체 캐시라고 하자.

  2. 단언: map[memaddr]는 존재하지 않는다.

  3. buffer를 고정 길이 메모리 버퍼를 생성하여 memaddr로부터 얻은 결과라고 하자.

  4. memory.[[Memory]]를 memaddr로 설정한다.

  5. memory.[[BufferObject]]를 buffer로 설정한다.

  6. Set map[memaddr]를 memory로 설정한다.

메모리 주소 memaddr로부터 메모리 객체를 생성하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Memory 객체 캐시라고 하자.

  2. 만약 map[memaddr]가 존재하면,

    1. map[memaddr]를 반환한다.

  3. memory를 새로운 Memory라고 하자.

  4. 초기화하여 memory를 memaddr로부터 설정한다.

  5. memory를 반환한다.

Memory(descriptor) 생성자는 호출되면 다음 단계를 수행합니다:
  1. descriptor["address"]가 존재하면, addrtype을 ToValueType(descriptor["address"])으로 두고, 그렇지 않으면 addrtype을 i32로 둡니다.

  2. initial을 ? AddressValueToU64(descriptor["initial"], addrtype)으로 둡니다.

  3. descriptor["maximum"]이 존재하면, maximum을 ? AddressValueToU64(descriptor["maximum"], addrtype)으로 두고, 그렇지 않으면 maximum을 비어 있는 값으로 둡니다.

  4. memtype을 메모리 타입 addrtype [initial .. maximum] page로 둡니다.

  5. memtype이 유효하지 않으면 RangeError 예외를 던집니다.

  6. store를 주변 에이전트의 연결된 저장소로 둡니다.

  7. (store, memaddr)를 mem_alloc(store, memtype)으로 둡니다. 할당에 실패하면 RangeError 예외를 던집니다.

  8. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  9. 초기화를 this에 대해 memaddr로부터 수행합니다.

memaddr의 Memory 버퍼를 새로 고치려면 다음 단계를 수행합니다:
  1. map을 주변 에이전트에 연결된 Memory 객체 캐시로 둡니다.

  2. 단언: map[memaddr]가 존재합니다.

  3. memory를 map[memaddr]로 둡니다.

  4. buffer를 memory.[[BufferObject]]로 둡니다.

  5. IsFixedLengthArrayBuffer(buffer)가 true이면,

    1. ! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.

    2. buffer를 고정 길이 메모리 버퍼를 생성한 결과로 두며, memaddr로부터 생성합니다.

    3. memory.[[BufferObject]]를 buffer로 설정합니다.

  6. 그렇지 않으면,

    1. block을 memaddr의 기본 메모리와 데이터 블록으로 동일시되는 것으로 둡니다.

    2. buffer.[[ArrayBufferData]]를 block으로 설정합니다.

    3. buffer.[[ArrayBufferByteLength]]를 block의 길이로 설정합니다.

메모리 주소 memaddr에 연결된 메모리 버퍼를 증가시키려면 delta만큼 증가시키며, 다음 단계를 수행합니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. ret를 mem_size(store, memaddr)로 둡니다.

  3. store를 mem_grow(store, memaddr, delta)로 둡니다.

  4. store가 오류이면 RangeError 예외를 던집니다.

  5. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  6. memaddr의 메모리 버퍼를 새로 고칩니다.

  7. ret를 반환합니다.

grow(delta) 메서드는 호출되면 다음 단계를 수행합니다:
  1. memaddr를 this.[[Memory]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. (addrtype, limits)를 mem_type(store, memaddr)으로 둡니다.

  4. delta64를 ? AddressValueToU64(delta, addrtype)으로 둡니다.

  5. ret를 메모리 버퍼를 증가시킨 결과로 두며, memaddr에 연결된 버퍼를 delta64만큼 증가시킵니다.

  6. U64ToAddressValue(ret, addrtype)를 반환합니다.

WebAssembly memory.grow x 명령어가 실행된 직후 다음 단계를 수행합니다:

  1. 스택의 맨 위가 i32.const (−1)이 아니고 스택의 맨 위가 i64.const (−1)도 아니면,

    1. frame을 현재 프레임으로 둡니다.

    2. 단언: 검증으로 인해 frame.module.memaddrs[x]가 존재합니다.

    3. memaddr를 frame.module.memaddrs[x]인 메모리 주소로 둡니다.

    4. memaddr의 메모리 버퍼를 새로 고칩니다.

toFixedLengthBuffer() 메서드는 호출될 때 다음 단계를 수행합니다:
  1. buffer를 this.[[BufferObject]]로 둡니다.

  2. IsFixedLengthArrayBuffer(buffer)가 true이면 buffer를 반환합니다.

  3. memaddr를 this.[[Memory]]로 둡니다.

  4. fixedBuffer를 memaddr에서 고정 길이 메모리 버퍼를 생성한 결과로 둡니다.

  5. ! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.

  6. this.[[BufferObject]]를 fixedBuffer로 설정합니다.

  7. fixedBuffer를 반환합니다.

toResizableBuffer() 메서드는 호출될 때 다음 단계를 수행합니다:
  1. memaddr를 this.[[Memory]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. memtype을 mem_type(store, memaddr)로 둡니다.

  4. memtype에 max가 없으면,

    1. TypeError 예외를 발생시킵니다.

  5. buffer를 this.[[BufferObject]]로 둡니다.

  6. IsFixedLengthArrayBuffer(buffer)가 false이면 buffer를 반환합니다.

  7. 단언: memtype에는 max가 있습니다.

  8. maxsize를 memtype의 max 값 * 65536으로 둡니다.

  9. resizableBuffer를 memaddr 및 maxsize에서 크기 조정 가능한 메모리 버퍼를 생성한 결과로 둡니다.

  10. ! DetachArrayBuffer(buffer, "WebAssembly.Memory")를 수행합니다.

  11. this.[[BufferObject]]를 resizableBuffer로 설정합니다.

  12. resizableBuffer를 반환합니다.

ArrayBuffer 객체가 Memory 객체에서 반환될 때에는 크기가 WebAssembly 페이지 크기(상수 65536)의 배수여야 합니다. 이러한 이유로 HostResizeArrayBuffer를 다음과 같이 다시 정의합니다.

추상 연산 HostResizeArrayBuffer는 인수 buffer(ArrayBuffer) 및 newLength를 받습니다. 호출될 때 다음 단계를 수행합니다.

  1. buffer.[[ArrayBufferDetachKey]]가 "WebAssembly.Memory"이면,

    1. map을 주변 에이전트의 연결된 Memory 객체 캐시로 둡니다.

    2. 단언: buffer는 map에 있는 정확히 하나의 값의 [[BufferObject]]입니다.

    3. 각각에 대해 map의 memaddr → mem에 대해,

      1. SameValue(mem.[[BufferObject]], buffer)가 true이면,

        1. 단언: buffer.[[ArrayBufferByteLength]] modulo 65536은 0입니다.

        2. lengthDelta를 newLength - buffer.[[ArrayBufferByteLength]]로 둡니다.

        3. lengthDelta < 0이거나 lengthDelta modulo 65536이 0이 아니면,

          1. RangeError 예외를 발생시킵니다.

        4. delta를 lengthDelta ÷ 65536으로 둡니다.

        5. memaddr과 연결된 메모리 버퍼를 delta만큼 확장합니다.

    4. handled를 반환합니다.

  2. 그렇지 않으면 unhandled를 반환합니다.

Memory의 buffer 속성의 getter는 this.[[BufferObject]]를 반환합니다.

5.4. 테이블

enum TableKind {
  "externref",
  "anyfunc",
  // 참고: 향후 반복에서 더 많은 값이 추가될 수 있음,
  // 예: typed function references, typed GC references
};

dictionary TableDescriptor {
  required TableKind element;
  required AddressValue initial;
  AddressValue maximum;
  AddressType address;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Table {
  constructor(TableDescriptor descriptor, optional any value);
  AddressValue grow(AddressValue delta, optional any value);
  any get(AddressValue index);
  undefined set(AddressValue index, optional any value);
  readonly attribute AddressValue length;
};

Table 객체는 여러 Instance 객체가 동시에 참조할 수 있는 단일 테이블 인스턴스를 나타낸다. 각 Table 객체는 [[Table]] 내부 슬롯을 가지며, 이는 하나의 테이블 주소이다.

테이블 주소 tableaddr로부터 테이블 객체 table을 초기화하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Table 객체 캐시라고 하자.

  2. 단언: map[tableaddr]는 존재하지 않는다.

  3. table.[[Table]]를 tableaddr로 설정한다.

  4. Set map[tableaddr]를 table로 설정한다.

테이블 주소 tableaddr로부터 테이블 객체를 생성하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Table 객체 캐시라고 하자.

  2. 만약 map[tableaddr]가 존재하면,

    1. map[tableaddr]를 반환한다.

  3. table을 새로운 Table라고 하자.

  4. 초기화하여 table을 tableaddr로부터 설정한다.

  5. table을 반환한다.

Table(descriptor, value) 생성자는 호출되면 다음 단계를 수행합니다:
  1. elementtype을 ToValueType(descriptor["element"])으로 둡니다.

  2. elementtype이 reftype이 아니면,

    1. 다음 예외를 던집니다: TypeError 예외입니다.

  3. descriptor["address"]가 존재하면, addrtype을 ToValueType(descriptor["address"])으로 두고, 그렇지 않으면 addrtype을 i32로 둡니다.

  4. initial을 ? AddressValueToU64(descriptor["initial"], addrtype)으로 둡니다.

  5. descriptor["maximum"]이 존재하면, maximum을 ? AddressValueToU64(descriptor["maximum"], addrtype)으로 두고, 그렇지 않으면 maximum을 비어 있는 값으로 둡니다.

  6. type을 테이블 타입 addrtype [initial .. maximum] elementtype으로 둡니다.

  7. type이 유효하지 않으면 RangeError 예외를 던집니다.

  8. value가 제공되지 않았다면,

    1. ref를 DefaultValue(elementtype)로 둡니다.

    2. 단언: ref는 오류가 아닙니다.

  9. 그렇지 않으면,

    1. ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.

  10. store를 주변 에이전트의 연결된 저장소로 둡니다.

  11. (store, tableaddr)를 table_alloc(store, type, ref)로 둡니다. 할당에 실패하면 RangeError 예외를 던집니다.

  12. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  13. 초기화할 대상은 this이며, tableaddr를 사용합니다.

grow(delta, value) 메서드는 호출되면 다음 단계를 수행합니다:
  1. tableaddr를 this.[[Table]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. initialSize를 table_size(store, tableaddr)로 둡니다.

  4. (addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.

  5. delta64를 ? AddressValueToU64(delta, addrtype)으로 둡니다.

  6. value가 제공되지 않았다면,

    1. ref를 DefaultValue(elementtype)로 둡니다.

    2. ref가 오류이면 TypeError 예외를 던집니다.

  7. 그렇지 않으면,

    1. ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.

  8. result를 table_grow(store, tableaddr, delta64, ref)로 둡니다.

  9. result가 오류이면 RangeError 예외를 던집니다.

    참고: 위 예외는 메모리 부족이나 잘못된 크기 매개변수 때문에 발생할 수 있습니다.

  10. 주변 에이전트의 연결된 저장소를 result로 설정합니다.

  11. U64ToAddressValue(initialSize, addrtype)을 반환합니다.

Table의 length 속성의 getter는 호출되면 다음 단계를 수행합니다:
  1. tableaddr를 this.[[Table]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. (addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.

  4. length64를 table_size(store, tableaddr)로 둡니다.

  5. U64ToAddressValue(length64, addrtype)을 반환합니다.

get(index) 메서드는 호출되면 다음 단계를 수행합니다:
  1. tableaddr를 this.[[Table]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. (addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.

  4. elementtype이 일치하면 exnref와,

    1. TypeError 예외를 던집니다.

  5. index64를 ? AddressValueToU64(index, addrtype)으로 둡니다.

  6. result를 table_read(store, tableaddr, index64)로 둡니다.

  7. result가 오류이면 RangeError 예외를 던집니다.

  8. ToJSValue(result)를 반환합니다.

set(index, value) 메서드는 호출되면 다음 단계를 수행합니다:
  1. tableaddr를 this.[[Table]]로 둡니다.

  2. store를 주변 에이전트의 연결된 저장소로 둡니다.

  3. (addrtype, limits, elementtype)을 table_type(store, tableaddr)으로 둡니다.

  4. elementtype이 일치하면 exnref와,

    1. TypeError 예외를 던집니다.

  5. index64를 ? AddressValueToU64(index, addrtype)으로 둡니다.

  6. value가 제공되지 않았다면,

    1. ref를 DefaultValue(elementtype)로 둡니다.

    2. ref가 오류이면 TypeError 예외를 던집니다.

  7. 그렇지 않으면,

    1. ref를 ? ToWebAssemblyValue(value, elementtype)으로 둡니다.

  8. store를 table_write(store, tableaddr, index64, ref)로 둡니다.

  9. store가 오류이면 RangeError 예외를 던집니다.

  10. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

5.5. 전역

enum ValueType {
  "i32",
  "i64",
  "f32",
  "f64",
  "v128",
  "externref",
  "anyfunc",
};

참고: 이 타입은 향후 버전의 WebAssembly에서 추가 case로 확장될 수 있다.

dictionary GlobalDescriptor {
  required ValueType value;
  boolean mutable = false;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Global {
  constructor(GlobalDescriptor descriptor, optional any v);
  any valueOf();
  attribute any value;
};

Global 객체는 여러 Instance 객체가 동시에 참조할 수 있는 단일 전역 인스턴스를 나타낸다. 각 Global 객체는 하나의 내부 슬롯을 가진다:

전역 주소 globaladdr로부터 전역 객체 global을 초기화하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Global 객체 캐시라고 하자.

  2. 단언: map[globaladdr]는 존재하지 않는다.

  3. global.[[Global]]를 globaladdr로 설정한다.

  4. Set map[globaladdr]를 global로 설정한다.

전역 주소 globaladdr로부터 전역 객체를 생성하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Global 객체 캐시라고 하자.

  2. 만약 map[globaladdr]가 존재하면,

    1. map[globaladdr]를 반환한다.

  3. global을 새로운 Global이라고 하자.

  4. 초기화하여 global을 globaladdr로부터 설정한다.

  5. global을 반환한다.

알고리즘 ToValueType(s)는 다음 단계를 수행합니다:
  1. s가 "i32"와 같으면 i32를 반환합니다.

  2. s가 "i64"와 같으면 i64를 반환합니다.

  3. s가 "f32"와 같으면 f32를 반환합니다.

  4. s가 "f64"와 같으면 f64를 반환합니다.

  5. s가 "v128"과 같으면 v128을 반환합니다.

  6. s가 "anyfunc"와 같으면 funcref를 반환합니다.

  7. s가 "externref"와 같으면 externref를 반환합니다.

  8. 단언: 이 단계에는 도달하지 않습니다.

알고리즘 DefaultValue(valuetype)는 다음 단계를 수행합니다:
  1. valuetype이 externref와 같으면 ! ToWebAssemblyValue(undefined, valuetype)를 반환합니다.

  2. val_default(valuetype)를 반환합니다.

다음 Global(descriptor, v) 생성자는 호출되면 다음 단계를 수행합니다:
  1. mutable을 descriptor["mutable"]로 둡니다.

  2. valuetype을 ToValueType(descriptor["value"])으로 둡니다.

  3. valuetype이 일치하면 v128 또는 exnref와,

    1. TypeError 예외를 던집니다.

  4. v가 제공되지 않았다면,

    1. value를 DefaultValue(valuetype)로 둡니다.

    2. 단언: value는 오류가 아닙니다.

  5. 그렇지 않으면,

    1. value를 ? ToWebAssemblyValue(v, valuetype)으로 둡니다.

  6. mutable이 true이면 globaltype을 mut valuetype으로 두고, 그렇지 않으면 globaltype을 valuetype으로 둡니다.

  7. store를 주변 에이전트의 연결된 저장소로 둡니다.

  8. (store, globaladdr)을 global_alloc(store, globaltype, value)로 둡니다.

  9. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  10. globaladdr로부터 this를 초기화합니다.

알고리즘 GetGlobalValue(Global global)은 다음 단계를 수행합니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. globaladdr를 global.[[Global]]로 둡니다.

  3. globaltype을 global_type(store, globaladdr)으로 둡니다.

  4. globaltype이 mut valuetype 형식이고 valuetype이 일치하면 v128 또는 exnref와, TypeError를 던집니다.

  5. value를 global_read(store, globaladdr)로 둡니다.

  6. ToJSValue(value)를 반환합니다.

Global의 value 속성의 getter는 호출되면 다음 단계를 수행합니다:
  1. GetGlobalValue(this)를 반환합니다.

Global의 value 속성 setter는 호출되면 다음 단계를 수행합니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. globaladdr를 this.[[Global]]로 둡니다.

  3. mut valuetype을 global_type(store, globaladdr)으로 둡니다.

  4. valuetype이 일치하면 v128 또는 exnref와, TypeError를 던집니다.

  5. mut가 비어 있으면 TypeError를 던집니다.

  6. value를 ? ToWebAssemblyValue(주어진 값, valuetype)으로 둡니다.

  7. store를 global_write(store, globaladdr, value)로 둡니다.

  8. store가 오류이면 RangeError 예외를 던집니다.

  9. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

valueOf() 메서드는 호출되면 다음 단계를 수행합니다:
  1. GetGlobalValue(this)를 반환합니다.

5.6. 내보낸 함수

WebAssembly 함수는 JavaScript에서 내보낸 함수로 제공된다. 내보낸 함수는 생성자가 아닌 내장 함수 객체이며, [[FunctionAddress]] 내부 슬롯을 가진다. 이 슬롯은 함수 주소를 저장하며, 이는 현재 agent의 연관 저장소에 상대적이다.

WebAssembly 함수의 이름 funcaddr은 다음 단계를 수행하여 찾습니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. funcinst를 store.funcs[funcaddr]로 둡니다.

  3. funcinst가 {type functype, hostcode hostfunc} 형식이면,

    1. 단언: hostfunc는 JavaScript 객체이며 IsCallable(hostfunc)은 true입니다.

    2. index를 funcaddr의 호스트 함수 인덱스로 둡니다.

  4. 그렇지 않으면,

    1. moduleinst를 funcinst.module로 둡니다.

    2. 단언: funcaddr는 moduleinst.funcs에 포함됩니다.

    3. index를 moduleinst.funcs에서 funcaddr가 발견되는 인덱스로 둡니다.

  5. ! ToString(index)을 반환합니다.

WebAssembly 함수 주소 funcaddr에서 새로운 내보낸 함수를 생성하려면 다음 단계를 수행합니다:
  1. map을 주변 에이전트에 연결된 내보낸 함수 캐시로 둡니다.

  2. map[funcaddr]가 존재하면,

    1. map[funcaddr]를 반환합니다.

  3. steps를 "내보낸 함수를 호출 funcaddr 인수를 사용하여."로 둡니다.

  4. realm을 현재 Realm으로 둡니다.

  5. store를 주변 에이전트의 연결된 저장소로 둡니다.

  6. functype을 func_type(store, funcaddr)으로 둡니다.

  7. func paramTypes → resultTypes를 functype의 확장 결과로 둡니다.

  8. arity를 paramTypes의 크기로 둡니다.

  9. name을 WebAssembly 함수의 이름 funcaddr로 둡니다.

  10. function을 CreateBuiltinFunction(steps, arity, name, « [[FunctionAddress]] », realm)으로 둡니다.

  11. function.[[FunctionAddress]]를 funcaddr로 설정합니다.

  12. 설정합니다: map[funcaddr]를 function으로 설정합니다.

  13. function을 반환합니다.

함수 주소 funcaddr와 JavaScript 인수의 목록 argValues를 사용하여 내보낸 함수를 호출하려면 다음 단계를 수행합니다:
  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. functype을 func_type(store, funcaddr)으로 둡니다.

  3. func parameters → results를 functype의 확장 결과로 둡니다.

  4. parameters 또는 results의 어떤 타입이든 일치하면 v128 또는 exnref와, TypeError를 던집니다.

    참고: 위 오류는 [[Call]] 메서드가 호출될 때마다 발생합니다.

  5. args를 « »로 둡니다.

  6. i를 0으로 둡니다.

  7. parameters의 각 t에 대해,

    1. argValues의 크기가 i보다 크면 arg를 argValues[i]로 둡니다.

    2. 그렇지 않으면 arg를 undefined로 둡니다.

    3. 추가합니다: ? ToWebAssemblyValue(arg, t)를 args에 추가합니다.

    4. i를 i + 1로 설정합니다.

  8. (store, ret)를 func_invoke(store, funcaddr, args)의 결과로 둡니다.

  9. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  10. ret가 오류이면 예외를 던집니다. 이 예외는 WebAssembly RuntimeError 예외여야 하지만, WebAssembly 오류 매핑에서 달리 지정한 경우는 제외합니다.

  11. ret가 exception exnaddr 형식이면,

    1. tagaddr를 exn_tag(store, exnaddr)로 둡니다.

    2. payload를 exn_read(store, exnaddr)로 둡니다.

    3. jsTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.

    4. tagaddr가 jsTagAddr와 같으면,

      1. ToJSValue(payload[0])를 던집니다.

    5. 그렇지 않으면,

      1. exception을 exnaddr에서 생성한 새로운 Exception으로 둡니다.

      2. exception을 던집니다.

  12. outArity를 ret의 크기로 둡니다.

  13. outArity가 0이면 undefined를 반환합니다.

  14. 그렇지 않고 outArity가 1이면 ToJSValue(ret[0])를 반환합니다.

  15. 그렇지 않으면,

    1. values를 « »로 둡니다.

    2. ret의 각 r에 대해,

      1. 추가합니다: ToJSValue(r)를 values에 추가합니다.

    3. CreateArrayFromList(values)를 반환합니다.

참고: 내보낸 함수를 호출하는 작업은 내장 함수 객체의 정의에 따라 피호출자 내보낸 함수의 [[Realm]]에서 실행됩니다.

참고: 내보낸 함수에는 [[Construct]] 메서드가 없으므로 new 연산자로 호출할 수 없습니다.

JavaScript 객체 func, 타입 functype 및 목록에 포함된 WebAssembly 값 arguments로부터 호스트 함수를 실행하려면 다음 단계를 수행합니다:
  1. func parameters → results를 functype의 확장 결과로 둡니다.

  2. parameters 또는 results의 어떤 타입이든 일치하면 v128 또는 exnref와, TypeError를 던집니다.

  3. jsArguments를 « »로 둡니다.

  4. arguments의 각 arg에 대해,

    1. 추가합니다: ToJSValue(arg)를 jsArguments에 추가합니다.

  5. ret를 ? Call(func, undefined, jsArguments)로 둡니다.

  6. resultsSize를 results의 크기로 둡니다.

  7. resultsSize가 0이면 « »를 반환합니다.

  8. 그렇지 않고 resultsSize가 1이면 « ? ToWebAssemblyValue(ret, results[0]) »를 반환합니다.

  9. 그렇지 않으면,

    1. method를 ? GetMethod(ret, %Symbol.iterator%)로 둡니다.

    2. method가 undefined이면 던집니다: TypeError를 던집니다.

    3. values를 ? IteratorToList(? GetIteratorFromMethod(ret, method))로 둡니다.

    4. wasmValues를 새로운 빈 목록으로 둡니다.

    5. values의 크기가 resultsSize와 다르면 TypeError 예외를 던집니다.

    6. values와 results에서 value와 resultType을 순서대로 쌍으로 묶어 각각에 대해 다음을 수행합니다.

      1. 추가합니다: ? ToWebAssemblyValue(value, resultType)을 wasmValues에 추가합니다.

    7. wasmValues를 반환합니다.

JavaScript 객체 func와 타입 functype으로부터 호스트 함수를 생성하려면 다음 단계를 수행합니다:
  1. 단언: IsCallable(func).

  2. stored settings를 현직 설정 객체로 둡니다.

  3. hostfunc을 다음 단계를 수행하는 호스트 함수로 둡니다. 이 함수는 인수 arguments로 호출될 때 다음을 수행합니다.

    1. realm을 func의 연결된 Realm으로 둡니다.

    2. relevant settings를 realm의 설정 객체로 둡니다.

    3. relevant settings를 사용하여 스크립트 실행을 준비합니다.

    4. stored settings를 사용하여 콜백 실행을 준비합니다.

    5. result를 func, functype 및 arguments로 호스트 함수를 실행한 결과로 둡니다.

    6. stored settings를 사용하여 콜백 실행 후 정리합니다.

    7. relevant settings를 사용하여 스크립트 실행 후 정리합니다.

    8. 단언: result.[[Type]]은 throw 또는 normal입니다.

    9. store를 주변 에이전트의 연결된 저장소로 둡니다.

    10. result.[[Type]]이 throw이면,

      1. v를 result.[[Value]]로 둡니다.

      2. v가 Exception을 구현하면,

        1. address를 v.[[Address]]로 둡니다.

      3. 그렇지 않으면,

        1. type을 JavaScript 예외 태그를 가져온 결과로 둡니다.

        2. payload를 ! ToWebAssemblyValue(v, externref)로 둡니다.

        3. (store, address)를 exn_alloc(store, type, « payload »)로 둡니다.

        4. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

      4. WebAssembly 명령어 (ref.exn address) (throw_ref)를 실행합니다.

    11. 그렇지 않으면 result.[[Value]]를 반환합니다.

  4. store를 주변 에이전트의 연결된 저장소로 둡니다.

  5. (store, funcaddr)를 func_alloc(store, functype, hostfunc)로 둡니다.

  6. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  7. funcaddr를 반환합니다.

알고리즘 ToJSValue(w)는 WebAssembly 값을 다음 단계에 따라 JavaScript 값으로 변환합니다:
  1. 단언: w는 v128.const v128 형식이 아닙니다.

  2. 단언: w는 ref.exn exnaddr 형식이 아닙니다.

  3. w가 i64.const u64 형식이면,

    1. i64를 signed_64(u64)로 둡니다.

    2. i64를 수학적 값으로 해석한 ℤ(i64)를 반환합니다.

  4. w가 i32.const u32 형식이면,

    1. i32를 signed_32(u32)로 둡니다.

    2. i32를 수학적 값으로 해석한 𝔽(i32)를 반환합니다.

  5. w가 f32.const f32 형식이면,

    1. f32가 +∞ 또는 −∞이면 각각 +∞𝔽 또는 -∞𝔽를 반환합니다.

    2. f32가 nan이면 NaN을 반환합니다.

    3. f32를 수학적 값으로 해석한 𝔽(f32)를 반환합니다.

  6. w가 f64.const f64 형식이면,

    1. f64가 +∞ 또는 −∞이면 각각 +∞𝔽 또는 -∞𝔽를 반환합니다.

    2. f64가 nan이면 NaN을 반환합니다.

    3. f64를 수학적 값으로 해석한 𝔽(f64)를 반환합니다.

  7. w가 ref.null 형식이면 null을 반환합니다.

  8. w가 ref.i31 u31 형식이면,

    1. i31을 signed_31(u31)로 둡니다.

    2. i31을 수학적 값으로 해석한 𝔽(i31)을 반환합니다.

  9. w가 ref.struct structaddr 형식이면 새로운 내보낸 GC 객체를 생성한 결과를 반환하며, structaddr와 "struct"를 사용합니다.

  10. w가 ref.array arrayaddr 형식이면 새로운 내보낸 GC 객체를 생성한 결과를 반환하며, arrayaddr와 "array"를 사용합니다.

  11. w가 ref.func funcaddr 형식이면 새로운 내보낸 함수를 funcaddr에서 생성한 결과를 반환합니다.

  12. w가 ref.host hostaddr 형식이면 호스트 값을 가져온 결과를 hostaddr에서 반환합니다.

  13. w가 ref.extern ref 형식이면 ToJSValue(ref)를 반환합니다.

참고: NaN과 같은 Number 값에는 관찰 가능한 다양한 NaN 페이로드가 있을 수 있습니다. 자세한 내용은 NumericToRawBytes를 참조하세요.

호스트 주소 hostaddr에서 호스트 값을 가져오려면 다음 단계를 수행합니다:

  1. map을 주변 에이전트에 연결된 호스트 값 캐시로 둡니다.

  2. 단언: map[hostaddr]가 존재합니다.

  3. map[hostaddr]를 반환합니다.

알고리즘 ToWebAssemblyValue(v, type)는 JavaScript 값을 다음 단계에 따라 WebAssembly 값으로 변환합니다:
  1. 단언: type은 v128이 아닙니다.

  2. 단언: type은 일치하지 않습니다: exnref와 일치하지 않습니다.

  3. type이 i64이면,

    1. i64를 ? ToBigInt64(v)로 둡니다.

    2. u64를 i64가 signed_64(u64)가 되는 부호 없는 정수로 둡니다.

    3. i64.const u64를 반환합니다.

  4. type이 i32이면,

    1. i32를 ? ToInt32(v)로 둡니다.

    2. u32를 i32가 signed_32(u32)가 되는 부호 없는 정수로 둡니다.

    3. i32.const u32를 반환합니다.

  5. type이 f32이면,

    1. number를 ? ToNumber(v)로 둡니다.

    2. number가 NaN이면,

      1. n을 canon32 ≤ n < 2signif(32)를 만족하는 구현 정의 정수로 둡니다.

      2. f32를 nan(n)으로 둡니다.

    3. 그렇지 않으면,

      1. f32를 number를 가장 가까운 표현 가능한 값으로 반올림한 값으로 두며 IEEE 754-2019의 최근접 짝수 반올림 모드를 사용합니다. [IEEE-754]

    4. f32.const f32를 반환합니다.

  6. type이 f64이면,

    1. number를 ? ToNumber(v)로 둡니다.

    2. number가 NaN이면,

      1. n을 canon64 ≤ n < 2signif(64)를 만족하는 구현 정의 정수로 둡니다.

      2. f64를 nan(n)으로 둡니다.

    3. 그렇지 않으면,

      1. f64를 number로 둡니다.

    4. f64.const f64를 반환합니다.

  7. type이 ref null heaptype 형식이면,

    1. v가 null이면,

      1. r을 ref.null로 둡니다.

    2. 그렇지 않고 match_valtype(type, ref null extern)이 true이면,

      1. ref를 ! ToWebAssemblyValue(v, ref any)로 둡니다.

      2. r을 ref.extern ref로 둡니다.

    3. 그렇지 않고 v가 내보낸 함수이며 match_valtype(type, ref null func)가 true이면,

      1. funcaddr를 v의 [[FunctionAddress]] 내부 슬롯 값으로 둡니다.

      2. r을 ref.func funcaddr로 둡니다.

    4. 그렇지 않고 v가 Number이며 v가 ? ToInt32(v)와 같고 ℝ(v) < 230이며 ℝ(v) ⩾ -230이면,

      1. i31을 ? ToInt32(v)로 둡니다.

      2. u31을 i31이 signed_31(u31)이 되는 부호 없는 정수로 둡니다.

      3. r을 ref.i31 u31로 둡니다.

    5. 그렇지 않고 v가 내보낸 GC 객체이면,

      1. objectaddr를 v의 [[ObjectAddress]] 내부 슬롯 값으로 둡니다.

      2. objectkind를 v의 [[ObjectKind]] 내부 슬롯 값으로 둡니다.

      3. objectkind가 "array"이면,

        1. r을 ref.array objectaddr로 둡니다.

      4. 그렇지 않고 objectkind가 "struct"이면,

        1. r을 ref.struct objectaddr로 둡니다.

    6. 그렇지 않으면,

      1. map을 주변 에이전트에 연결된 호스트 값 캐시로 둡니다.

      2. map[hostaddr]가 v와 동일한 호스트 주소 hostaddr가 존재하면,

        1. ref.host hostaddr를 반환합니다.

      3. hostaddr를 map[hostaddr]가 존재하지 않는 가장 작은 호스트 주소로 두며, 존재 여부는 false입니다.

      4. 설정합니다: map[hostaddr]를 v로 설정합니다.

      5. r을 ref.host hostaddr로 둡니다.

    7. store를 주변 에이전트의 연결된 저장소로 둡니다.

    8. actualtype을 ref_type(store, r)으로 둡니다.

    9. match_valtype(actualtype, type)이 false이면,

      1. TypeError를 던집니다.

    10. r을 반환합니다.

  8. 단언: 이 단계에는 도달하지 않습니다.

알고리즘 AddressValueToU64(v, addrtype)는 IDL 값을 임베딩 연산에서 사용할 WebAssembly u64로 변환합니다. 이 알고리즘은 AddressType "i32"에 대해 [EnforceRange] unsigned long처럼 동작하고, AddressType "i64"에도 이러한 의미 체계를 확장하도록 설계되었으며, 다음 단계를 수행합니다:
  1. jsValue를 v를 JavaScript 값으로 변환한 값으로 둡니다.

    참고: IDL any 타입은 JavaScript 값을 단순히 감싸는 래퍼가 아니라 구별된 유니언입니다.

  2. addrtype이 i32이면,

    1. n을 ? ConvertToInt(jsValue, 32, "unsigned")로 두며, 대상 타입에는 [EnforceRange]가 연결되어 있습니다.

      참고: 이는 JavaScript 변환 규칙과 동일하며, [EnforceRange] unsigned long에 적용됩니다.

    2. ℝ(n)을 WebAssembly u64로 반환합니다.

  3. addrtype이 i64이면,

    1. n을 ? ToBigInt(jsValue)로 둡니다.

    2. r을 ℝ(n)로 둡니다.

    3. r < 0 또는 r > 264 − 1이면 던집니다: TypeError를 던집니다.

      참고: 이 연산은 [EnforceRange]를 모방하도록 설계되었습니다.

    4. r을 WebAssembly u64로 반환합니다.

  4. 단언: 이 단계에는 도달하지 않습니다.

알고리즘 U64ToAddressValue(v, addrtype)는 WebAssembly 임베딩 연산의 u64 값을 AddressType에 맞는 AddressValue 변형으로 변환하며, 다음 단계를 수행합니다:
  1. addrtype이 i32이면 v를 수학적 값으로 해석한 𝔽(v)를 반환합니다.

  2. 그렇지 않고 addrtype이 i64이면 v를 수학적 값으로 해석한 ℤ(v)를 반환합니다.

  3. 단언: 이 단계에는 도달하지 않습니다.

5.7. 태그

5.7.1. 태그 타입

dictionary TagType {
  required sequence<ValueType> parameters;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Tag {
  constructor(TagType type);
};

Tag 값은 예외 태그를 나타낸다.

Tag 객체를 초기화하려면, 태그 주소 tagAddress로부터 tag에 대해 다음 단계를 수행한다:

  1. map을 현재 agent에 연관된 Tag 객체 캐시라고 하자.

  2. 단언: map[tagAddress]는 존재하지 않는다.

  3. tag.[[Address]]를 tagAddress로 설정한다.

  4. Set map[tagAddress]를 tag로 설정한다.

태그 주소 tagAddress로부터 Tag 객체를 생성하려면, 다음 단계를 수행한다:
  1. map을 현재 agent에 연관된 Tag 객체 캐시라고 하자.

  2. 만약 map[tagAddress]가 존재하면,

    1. map[tagAddress]를 반환한다.

  3. tag를 새로운 Tag라고 하자.

  4. 초기화하여 tag를 tagAddress로부터 설정한다.

  5. tag를 반환한다.

다음 new Tag(type) 생성자 단계는 다음과 같습니다:

  1. parameters를 type["parameters"]로 둡니다.

  2. wasmParameters를 «»로 둡니다.

  3. 각각에 대해 paramType을 parameters에서 가져와,

    1. 추가: ToValueType(paramType)을 wasmParameters에 추가합니다.

  4. tagtype을 다음 조건을 만족하는 정의된 타입으로 둡니다. 즉, func wasmParameters → « »가 확장 결과인 tagtype입니다.

  5. store를 주변 에이전트의 연결된 저장소로 둡니다.

  6. (store, tagAddress)를 tag_alloc(store, tagtype)로 둡니다.

  7. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  8. 초기화를 수행하며 this에 tagAddress를 사용합니다.

5.8. 가비지 컬렉션된 객체

WebAssembly struct 또는 array는 JavaScript에서 Exported GC Object로 제공된다. Exported GC Object는 가비지 컬렉션되는 WebAssembly 참조 값을 감싸는 exotic object이다. Exported GC Object에 대한 대부분의 JavaScript 연산은 예외를 던지거나 undefined를 반환한다.

참고: 이러한 연산은 향후 JavaScript에서 WebAssembly struct 및 array와 더 풍부한 상호작용을 허용하도록 정교화될 수 있다.

Exported GC Object는 [[ObjectAddress]] 내부 슬롯을 포함하며, 이는 object address를 저장한다. 이 주소는 현재 agent의 연관 저장소에 상대적이며, [[ObjectKind]] 내부 슬롯도 포함하는데, 여기에는 문자열 값 "struct" 또는 "array"가 저장된다.

Exported GC Object의 내부 메서드는 다음 구현을 사용한다.

Exported GC Object의 [[GetPrototypeOf]] 내부 메서드 O는 인수를 받지 않고 null을 반환한다. 호출되면 다음 단계를 수행한다:
  1. null을 반환한다.

Exported GC Object의 [[SetPrototypeOf]] 내부 메서드 O는 인수 V (Object 또는 null)를 받고 boolean을 반환한다. 호출되면 다음 단계를 수행한다:
  1. false를 반환한다.

Exported GC Object의 [[IsExtensible]] 내부 메서드 O는 인수를 받지 않고 boolean을 반환한다. 호출되면 다음 단계를 수행한다:
  1. false를 반환한다.

Exported GC Object의 [[PreventExtensions]] 내부 메서드 O는 인수를 받지 않고 boolean을 반환한다. 호출되면 다음 단계를 수행한다:
  1. false를 반환한다.

Exported GC Object의 [[GetOwnProperty]] 내부 메서드 O는 인수 P (property key)를 받고 undefined를 반환한다. 호출되면 다음 단계를 수행한다:
  1. undefined를 반환한다.

Exported GC Object의 [[DefineOwnProperty]] 내부 메서드 O는 인수 P (property key) 및 Desc (property descriptor)를 받고 boolean을 반환한다. 호출되면 다음 단계를 수행한다:
  1. false를 반환한다.

Exported GC Object의 [[HasProperty]] 내부 메서드 O는 인수 P (property key)를 받고 boolean을 반환한다. 호출되면 다음 단계를 수행한다:
  1. false를 반환한다.

Exported GC Object의 [[Get]] 내부 메서드 O는 인수 P (property key) 및 Receiver (ECMAScript 언어 값)를 받고 undefined를 반환한다. 호출되면 다음 단계를 수행한다:
  1. undefined를 반환한다.

Exported GC Object의 [[Set]] 내부 메서드 O는 인수 P (property key), V (ECMAScript 언어 값), 그리고 Receiver (ECMAScript 언어 값)를 받고 예외를 던진다. 호출되면 다음 단계를 수행한다:
  1. TypeError를 던진다.

Exported GC Object의 [[Delete]] 내부 메서드 O는 인수 P (property key)를 받고 예외를 던진다. 호출되면 다음 단계를 수행한다:
  1. TypeError를 던진다.

Exported GC Object의 [[OwnPropertyKeys]] 내부 메서드 O는 인수를 받지 않고 리스트를 반환한다. 호출되면 다음 단계를 수행한다:
  1. « »를 반환합니다.

WebAssembly object address objectaddr 및 문자열 objectkind로부터 새로운 Exported GC Object를 생성하려면, 다음 단계를 수행한다:
  1. 단언: objectkind는 "array" 또는 "struct" 중 하나이다.

  2. map을 현재 agent에 연관된 exported GC object cache라고 하자.

  3. 만약 map[objectaddr]가 존재하면,

    1. map[objectaddr]를 반환한다.

  4. object를 MakeBasicObject(« [[ObjectAddress]], [[ObjectKind]] »)라고 하자.

  5. object.[[ObjectAddress]]를 objectaddr로 설정한다.

  6. object.[[ObjectKind]]를 objectkind로 설정한다.

  7. object.[[GetPrototypeOf]]를 Exported GC Object의 [[GetPrototypeOf]] 내부 메서드에 명시된 대로 설정한다.

  8. object.[[SetPrototypeOf]]를 Exported GC Object의 [[SetPrototypeOf]] 내부 메서드에 명시된 대로 설정한다.

  9. object.[[IsExtensible]]를 Exported GC Object의 [[IsExtensible]] 내부 메서드에 명시된 대로 설정한다.

  10. object.[[PreventExtensions]]를 Exported GC Object의 [[PreventExtensions]] 내부 메서드에 명시된 대로 설정한다.

  11. object.[[GetOwnProperty]]를 Exported GC Object의 [[GetOwnProperty]] 내부 메서드에 명시된 대로 설정한다.

  12. object.[[DefineOwnProperty]]를 Exported GC Object의 [[DefineOwnProperty]] 내부 메서드에 명시된 대로 설정한다.

  13. object.[[HasProperty]]를 Exported GC Object의 [[HasProperty]] 내부 메서드에 명시된 대로 설정한다.

  14. object.[[Get]]를 Exported GC Object의 [[Get]] 내부 메서드에 명시된 대로 설정한다.

  15. object.[[Set]]를 Exported GC Object의 [[Set]] 내부 메서드에 명시된 대로 설정한다.

  16. object.[[Delete]]를 Exported GC Object의 [[Delete]] 내부 메서드에 명시된 대로 설정한다.

  17. object.[[OwnPropertyKeys]]를 Exported GC Object의 [[OwnPropertyKeys]] 내부 메서드에 명시된 대로 설정한다.

  18. Set map[objectaddr]를 object로 설정한다.

  19. object를 반환한다.

5.9. 예외

dictionary ExceptionOptions {
  boolean traceStack = false;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Exception {
  constructor(Tag exceptionTag, sequence<any> payload, optional ExceptionOptions options = {});
  any getArg(Tag exceptionTag, [EnforceRange] unsigned long index);
  boolean is(Tag exceptionTag);
  readonly attribute (DOMString or undefined) stack;
};

Exception 값은 예외를 나타낸다.

Exception 객체를 초기화하려면, Exception address exnAddress로부터 exn에 대해 다음 단계를 수행한다:

  1. map을 현재 agent에 연관된 Exception 객체 캐시라고 하자.

  2. 단언: map[exnAddress]는 존재하지 않는다.

  3. exn.[[Address]]를 exnAddress로 설정한다.

  4. Set map[exnAddress]를 exn로 설정한다.

  5. store를 현재 agent의 연관 저장소라고 하자.

  6. tagaddr를 exn_tag(store, exnAddress)라고 하자.

  7. payload를 exn_read(store, exnAddress)라고 하자.

  8. exn.[[Type]]를 tagaddr로 설정한다.

  9. exn.[[Payload]]를 payload로 설정한다.

  10. exn.[[Stack]]를 undefined로 설정한다.

Exception 객체를 생성하려면, exception address exnAddress로부터 다음 단계를 수행한다:

  1. map을 현재 agent에 연관된 Exception 객체 캐시라고 하자.

  2. 만약 map[exnAddress]가 존재하면,

    1. map[exnAddress]를 반환한다.

  3. exn을 새로운 Exception라고 하자.

  4. 초기화하여 exn을 exnAddress로부터 설정한다.

  5. exn을 반환한다.

new Exception(exceptionTag, payload, options) 생성자의 단계는 다음과 같습니다:

  1. JSTagAddr를 JavaScript 예외 태그를 가져온 결과로 둡니다.

  2. exceptionTag.[[Address]]가 JSTagAddr와 같으면,

    1. TypeError를 던집니다.

  3. store를 주변 에이전트의 연결된 저장소로 둡니다.

  4. func types → « »를 확장 결과로 두며, 이는 tag_type(store, exceptionTag.[[Address]])를 확장한 값입니다.

  5. types의 크기가 payload의 크기와 다르면,

    1. TypeError를 던집니다.

  6. wasmPayload를 « »로 둡니다.

  7. 각 value와 resultType을 payload와 types에서 순서대로 짝지어,

    1. resultType이 일치하는 대상이 v128 또는 exnref이면,

      1. TypeError를 던집니다.

    2. 추가: ? ToWebAssemblyValue(value, resultType)를 wasmPayload에 추가합니다.

  8. (store, exceptionAddr)를 exn_alloc(store, exceptionTag.[[Address]], wasmPayload)로 둡니다.

  9. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  10. 초기화할 대상은 this이며, exceptionAddr를 사용합니다.

  11. options["traceStack"]이 true이면,

    1. this.[[Stack]]을 현재 호출 스택의 DOMString 표현 또는 undefined로 설정합니다.

getArg(exceptionTag, index) 메서드의 단계는 다음과 같습니다:

  1. store를 주변 에이전트의 연결된 저장소로 둡니다.

  2. this.[[Type]]이 exceptionTag.[[Address]]와 같지 않으면,

    1. TypeError를 던집니다.

  3. tagaddr를 exn_tag(store, this.[[Address]])로 둡니다.

  4. payload를 exn_read(store, this.[[Address]])로 둡니다.

  5. 단언: tagaddr는 this.[[Type]]과 같습니다.

  6. index ≥ payload의 크기이면,

    1. RangeError를 던집니다.

  7. func types → « »를 확장 결과로 두며, 이는 tag_type(store, tagaddr)를 확장한 값입니다.

  8. types[index]가 일치하는 대상이 v128 또는 exnref이면,

    1. TypeError를 던집니다.

  9. ToJSValue(payload[index])를 반환합니다.

is(exceptionTag) 메서드의 단계는 다음과 같습니다:

  1. this.[[Type]]이 exceptionTag.[[Address]]와 같지 않으면,

    1. false를 반환합니다.

  2. true를 반환합니다.

stack getter의 단계는 다음과 같습니다:

  1. this.[[Stack]]을 반환합니다.

5.9.1. JavaScript 예외

JavaScript 예외 태그는 태그 주소이며 주변 에이전트에 연결됩니다. 이 태그는 에이전트의 연결된 저장소에 처음 사용될 때 할당되어 캐시됩니다. 이 태그의 태그 타입은 항상 « externref » → « »입니다.

JavaScript 예외 태그를 가져오려면, 다음 단계를 수행합니다:

  1. 주변 에이전트에 연결된 JavaScript 예외 태그가 초기화되어 있다면,

    1. 다음 주변 에이전트에 연결된 JavaScript 예외 태그를 반환합니다.

  2. tagtype을 다음 조건을 만족하는 정의된 타입으로 둡니다. 즉, func « externref » → « »가 확장 결과가 되는 tagtype입니다.

  3. store를 주변 에이전트의 연결된 저장소로 둡니다.

  4. (store, tagAddress)를 tag_alloc(store, tagtype)로 둡니다.

  5. 주변 에이전트의 연결된 저장소를 store로 설정합니다.

  6. 주변 에이전트에 연결된 JavaScript 예외 태그를 tagAddress로 설정합니다.

  7. tagAddress를 반환합니다.

5.10. 오류 객체

WebAssembly는 다음 Error 클래스를 정의한다: CompileError, LinkError, 그리고 RuntimeError.

WebAssembly 네임스페이스의 namespace object가 생성될 때, 다음 단계를 실행해야 한다:
  1. namespaceObject를 그 namespace object라고 하자.

  2. 각각에 대해 error of « "CompileError", "LinkError", "RuntimeError" »,

    1. constructor를 새 객체라고 하자. 이 객체는 NativeError Object Structure를 구현하며, NativeError가 error로 설정된다.

    2. ! DefineMethodProperty(namespaceObject, error, constructor, false)를 수행한다.

참고: 이것은 CompileError, LinkError, 그리고 RuntimeError 클래스를 WebAssembly 네임스페이스에 정의하며, 이 명세에서 정의된 API가 이를 생성한다. 이들은 TypeError 및 RangeError와 같은 네이티브 JavaScript 오류와 동일한 인터페이스를 노출한다.

참고: 현재는 이 동작을 Web IDL을 사용해 정의할 수 없다.

6. 빌트인

JS-API는 모듈을 컴파일할 때 options를 통해 가져올 수 있는 빌트인 함수 집합을 정의한다. WebAssembly 빌트인 함수는 기존 JavaScript 빌트인을 반영하지만, 최소한의 오버헤드로 WebAssembly 함수로 직접 사용할 수 있도록 조정된다.

모든 빌트인 함수는 집합으로 그룹화된다. 모든 빌트인 집합에는 이름이 있으며 이는 WebAssemblyCompileOptions에서 사용되고, 또한 wasm: 접두사가 붙은 정규화된 이름이 있으며 이는 import 조회 중에 사용된다.

빌트인 집합의 빌트인 가져오기를 builtinSetName으로 수행하려면, 다음 단계를 수행한다:

  1. 이 절 안에서 정의된 이름 builtinSetName을 가진 집합에 대해, (name, funcType, steps)의 리스트를 반환한다.

빌트인 찾기를 import와 활성화된 빌트인 builtinSetNames로 수행하려면, 다음 단계를 수행한다:

  1. 단언: 빌트인 집합 이름 검증 builtinSetNames는 true이다.

  2. importModuleName을 import[0]이라고 하자.

  3. importName을 import[1]이라고 하자.

  4. 각각에 대해 builtinSetName of builtinSetNames,

    1. 만약 builtinSetName이 빌트인 집합을 가리키지 않으면, continue한다.

    2. builtinSetQualifiedName을 builtinSetName 앞에 "wasm:"를 붙인 것이라고 하자.

    3. 만약 importModuleName이 builtinSetQualifiedName과 같으면,

      1. builtins를 빌트인 집합의 빌트인 가져오기 builtinSetName의 결과라고 하자.

      2. 각각에 대해 builtin of builtins,

        1. builtinName을 builtin[0]이라고 하자.

        2. 만약 importName이 builtinName과 같으면, (builtinSetName, builtin)를 반환한다.

  5. null을 반환한다.

빌트인 집합 이름 검증을 builtinSetNames로 수행하려면, 다음 단계를 수행한다:

  1. 만약 builtinSetNames가 중복을 하나라도 포함하면, false를 반환한다.

  2. true를 반환한다.

빌트인 함수 생성을 타입 funcType 및 실행 단계 steps로부터 수행하려면, 다음 단계를 수행한다:

  1. hostfunc를 호스트 함수라고 하며, 호출되면 steps를 실행한다.

  2. store를 현재 agent의 연관 저장소라고 하자.

  3. (store, funcaddr)를 func_alloc(store, funcType, hostfunc)라고 하자.

  4. 현재 agent의 연관 저장소를 store로 설정한다.

  5. funcaddr를 반환한다.

이름이 builtinSetName인 내장 집합을 인스턴스화하려면 다음 단계를 수행합니다:

  1. builtins를 builtinSetName에 대해 내장 집합의 내장 기능을 가져온 결과로 둡니다.

  2. exportsObject를 OrdinaryObjectCreate(null)로 둡니다.

  3. builtins의 각 (name, funcType, steps)에 대해 각각에 대해,

    1. funcaddr를 funcType 및 steps를 사용하여 내장 함수를 생성한 결과로 둡니다.

    2. func를 funcaddr에서 새 내보낸 함수를 생성한 결과로 둡니다.

    3. value를 func로 둡니다.

    4. status를 ! CreateDataProperty(exportsObject, name, value)로 둡니다.

    5. 단언: status는 true입니다.

  4. exportsObject를 반환합니다.

import 및 활성화된 내장 기능 builtinSetNames을 사용하여 내장 기능에 대한 가져오기를 검증하려면 다음 단계를 수행합니다:

  1. 단언: 내장 집합 이름을 검증한 builtinSetNames의 결과는 true입니다.

  2. maybeBuiltin을 import 및 builtinSetNames에 대해 내장 기능을 찾은 결과로 둡니다.

  3. maybeBuiltin이 null이면 true를 반환합니다.

  4. importExternType을 import[2]로 둡니다.

  5. builtinFuncType을 maybeBuiltin[1][1]로 둡니다.

  6. builtinExternType을 func |builtinFuncType|으로 둡니다.

  7. match_externtype(builtinExternType, importExternType)을 반환합니다.

6.1. 문자열 빌트인

문자열 빌트인은 String 빌트인 객체의 인터페이스를 조정한다. 이 집합의 이름은 js-string이고, 정규화된 이름은 wasm:js-string이다.

참고: 이 절의 알고리즘은 JS 빌트인으로서 String에 정의된 것들을 참조한다. 이들은 실제 빌트인을 가리키며, String 객체에 대해 동적 조회를 수행하지 않는다.

6.1.1. 추상 연산

추상 연산 UnwrapString(v)은 호출되면, 다음 단계를 수행한다:

  1. 만약 v가 String이 아니면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  2. v를 반환한다

FromCharCode(v) 추상 연산은 호출되면 다음 단계를 수행합니다:

  1. 단언: v는 i32 타입입니다.

  2. ! Call(String.fromCharCode, undefined, « ToJSValue(v) »)를 반환합니다.

CharCodeAt(string, index) 추상 연산은 호출되면 다음 단계를 수행합니다:

  1. 단언: index는 i32 타입입니다.

  2. ! Call(String.prototype.charCodeAt, string, « ToJSValue(index) »)를 반환합니다.

6.1.2. cast

이 빌트인의 funcType은 (rec (type (func (param externref) (result (ref extern))))).0이다.

이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. ? UnwrapString(v)를 반환한다

6.1.3. test

이 빌트인의 funcType은 (rec (type (func (param externref) (result i32)))).0이다.

이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. 만약 v가 String이 아니면,

    1. 0을 반환한다.

  2. 1을 반환한다.

6.1.4. fromCharCodeArray

arrayType을 (rec (type (array (mut i16)))).0이라고 하자.

이 빌트인의 funcType은 (rec (type (func (param (ref null arrayType) i32 i32) (result (ref extern))))).0이다.

이 빌트인이 매개변수 array, start, 그리고 end와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. 만약 array가 null이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  2. length를 array 안의 원소 수라고 하자.

  3. 만약 start > end 또는 end > length이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  4. result를 빈 문자열이라고 하자.

  5. i를 start라고 하자.

  6. i < end인 동안:

    1. charCode를 array의 인덱스 i에 저장된 원소의 값이라고 하자.

    2. charCodeString을 FromCharCode(charCode)라고 하자.

    3. result를 result와 charCodeString의 연결이라고 하자.

    4. i를 i + 1로 설정한다.

  7. result를 반환한다.

6.1.5. intoCharCodeArray

arrayType을 (rec (type (array (mut i16)))).0이라고 하자.

이 빌트인의 funcType은 (rec (type (func (param externref (ref null arrayType) i32) (result i32)))).0이다.

이 빌트인이 매개변수 string, array, 그리고 start와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. 만약 array가 null이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  2. string을 ? UnwrapString(string)라고 하자.

  3. stringLength를 string의 길이라고 하자.

  4. arrayLength를 array 안의 원소 수라고 하자.

  5. 만약 start + stringLength > arrayLength이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  6. i를 0이라고 하자.

  7. i < stringLength인 동안:

    1. charCode를 CharCodeAt(string, i)라고 하자.

    2. array 안의 인덱스 start + i 위치의 원소를 ToWebAssemblyValue(charCode, i32)로 설정한다.

    3. i를 i + 1로 설정한다.

  8. stringLength를 반환한다.

6.1.6. fromCharCode

이 빌트인의 funcType은 (rec (type (func (param i32) (result (ref extern))))).0이다.

이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. FromCharCode(v)를 반환한다.

6.1.7. fromCodePoint

이 빌트인의 funcType은 (rec (type (func (param i32) (result externref)))).0이다.

이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. 만약 v > 0x10ffff이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  2. ! Call(String.fromCodePoint, undefined, « ToJSValue(v) »)를 반환한다.

6.1.8. charCodeAt

이 함수의 타입은 (rec (type (func (param externref i32) (result i32)))).0이다.

이 빌트인이 매개변수 string 및 index와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. string을 ? UnwrapString(string)라고 하자.

  2. length를 string의 길이 라고 하자.

  3. 만약 index >= length이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  4. CharCodeAt(string, index)를 반환한다.

6.1.9. codePointAt

이 함수의 타입은 (rec (type (func (param externref i32) (result i32)))).0이다.

이 빌트인이 매개변수 string 및 index와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. string을 ? UnwrapString(string)라고 하자.

  2. length를 string의 길이 라고 하자.

  3. 만약 index >= length이면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 던진다.

  4. ! Call(String.prototype.codePointAt, string, « ToJSValue(index) »)를 반환한다.

6.1.10. length

이 빌트인의 funcType은 (rec (type (func (param externref) (result i32)))).0이다.

이 빌트인이 매개변수 v와 함께 호출되면, 다음 단계를 실행해야 한다:

  1. string을 ? UnwrapString(v)라고 하자.

  2. string의 길이를 반환한다.

6.1.11. concat

이 빌트인의 funcType은 (rec (type (func (param externref externref) (result (ref extern))))).0이다.

이 내장 기능이 매개변수 first 및 second와 함께 호출되면 다음 단계를 반드시 실행해야 합니다:

  1. first를 ? UnwrapString(first)으로 둡니다.

  2. second를 ? UnwrapString(second)으로 둡니다.

  3. ! Call(String.prototype.concat, first, « second »)를 반환합니다.

6.1.12. substring

이 빌트인의 funcType은 (rec (type (func (param externref i32 i32) (result (ref extern))))).0이다.

이 내장 기능이 매개변수 string, start 및 end와 함께 호출되면 다음 단계를 반드시 실행해야 합니다:

  1. string을 ? UnwrapString(string)으로 둡니다.

  2. length를 string의 길이로 둡니다.

  3. start > end이거나 start > length이면,

    1. 빈 문자열을 반환합니다.

  4. ! Call(String.prototype.substring, string, « ToJSValue(start), ToJSValue(end) »)를 반환합니다.

6.1.13. equals

이 빌트인의 funcType은 (rec (type (func (param externref externref) (result i32)))).0이다.

참고: null 문자열도 의미 있게 비교 가능하므로 명시적으로 동등성 비교를 허용한다.

이 내장 기능이 매개변수 first 및 second와 함께 호출되면, 다음 단계를 반드시 실행해야 합니다:

  1. first가 null이 아니고 first가 String이 아니면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 발생시킵니다.

  2. second가 null이 아니고 second가 String이 아니면,

    1. 트랩이 실행된 것처럼 RuntimeError 예외를 발생시킵니다.

  3. IsStrictlyEqual(first, second)이 true이면,

    1. 1을 반환합니다.

  4. 0을 반환합니다.

6.1.14. compare

이 빌트인의 funcType은 (rec (type (func (param externref externref) (result i32)))).0이다.

이 내장 기능이 매개변수 first 및 second와 함께 호출되면, 다음 단계를 반드시 실행해야 합니다:

  1. first를 ? UnwrapString(first)으로 둡니다.

  2. second를 ? UnwrapString(second)으로 둡니다.

  3. IsStrictlyEqual(first, second)이 true이면,

    1. 0을 반환합니다.

  4. ! IsLessThan(first, second, true)가 true이면,

    1. -1을 반환합니다.

  5. 1을 반환합니다.

7. 오류 조건의 JavaScript 매핑

WebAssembly 프로그램을 실행하면 WebAssembly 코드의 실행을 중단시키는 특정 사건을 만나게 된다. WebAssembly 코드는 (현재) 이러한 조건을 포착할 방법이 없으므로 예외는 반드시 이를 둘러싼 비-WebAssembly 호출자(브라우저이든, JavaScript이든 다른 런타임 시스템이든)로 전파되며, 그곳에서 일반적인 JavaScript 예외처럼 처리된다.

WebAssembly가 import를 통해 JavaScript를 호출하고 JavaScript가 예외를 던지면, 그 예외는 WebAssembly 활성화를 통과하여 외부 호출자로 전파된다.

JavaScript 예외는 처리될 수 있고, 트랩이 처리된 후에도 JavaScript는 계속 WebAssembly export를 호출할 수 있으므로, 트랩은 일반적으로 미래의 실행을 막지 않는다.

7.1. 스택 오버플로

WebAssembly 코드에서 스택 오버플로가 발생할 때마다, JavaScript에서 스택 오버플로가 발생했을 때와 같은 종류의 예외가 던져진다. 여기서의 구체적인 예외는 두 경우 모두 구현 정의이다.

참고: ECMAScript는 스택 오버플로 시의 동작을 어떤 식으로도 명시하지 않는다; 구현들은 RangeError, InternalError 또는 Error를 던지는 것으로 관찰되었다. 여기서는 어느 쪽이든 유효하다.

7.2. 메모리 부족

검증, 컴파일 또는 인스턴스화 중 메모리가 부족해질 때마다, JavaScript의 메모리 부족 조건과 같은 종류의 예외가 던져진다. 여기서의 구체적인 예외는 두 경우 모두 구현 정의이다.

참고: ECMAScript는 메모리 부족 조건에서의 동작을 어떤 식으로도 명시하지 않는다; 구현들은 OOMError를 던지거나 충돌하는 것으로 관찰되었다. 여기서는 둘 다 유효하다.

큰 테이블 또는 메모리의 할당 실패는 다음 중 하나를 초래할 수 있다 향후 개정에서는 대량의 메모리 할당에 대해 보다 신뢰 가능하고 복구 가능한 오류를 다시 고려할 수 있다.

추가 논의는 Issue 879를 참조하라.

8. 구현 정의 한계

WebAssembly 코어 명세는 구현이 모듈의 구문 구조에 대한 한계를 정의할 수 있도록 허용한다. WebAssembly의 각 임베딩은 자체 한계를 선택해 정의할 수 있지만, 예측 가능성을 위해 이 문서에서 설명하는 표준 WebAssembly JavaScript Interface는 다음과 같은 정확한 한계를 정의한다. 구현은 다음 한계 중 하나를 초과하는 모듈을 CompileError와 함께 거부해야 한다. 실제로는 구현이 이러한 한계보다 작은 유효한 모듈에 대해서도 리소스가 부족해질 수 있다.

구현은 런타임 중 다음 한계 중 하나가 초과되면 RuntimeError를 던져야 한다: 실제로는 구현이 이러한 한계보다 작은 유효한 모듈에 대해서도 리소스가 부족해질 수 있다.

9. 보안 및 개인정보 보호 고려 사항

이 절은 비규범적이다.

이 문서는 WebAssembly를 위한 호스트 환경을 정의한다. 이는 WebAssembly 인스턴스가 import를 통해 JavaScript 객체와 함수를 import object로부터 가져올 수 있게 하지만, 그 외에는 임베딩 환경에 대한 접근을 제공하지 않는다. 따라서 WebAssembly 인스턴스는 JavaScript와 동일한 제약에 묶인다.

10. 변경 이력

이 절은 비규범적이다.

WebAssembly 명세의 원래 1.0 릴리스 이후, 여러 확장 제안이 통합되었다. 다음 절에서는 무엇이 변경되었는지에 대한 개요를 제공한다.

10.1. 릴리스 2.0

다중 값

여러 값은 JavaScript 함수로부터 그리고 JavaScript 함수로 Array 객체로서 반환될 수 있다.

BigInt 통합

WebAssembly i64 값은 JavaScript와 주고받을 수 있다 (import되거나 export된 global, table get 또는 set 연산, 함수 반환값 또는 인수를 통해) BigInt 객체로서.

참조 타입

JavaScript 값은 WebAssembly와 주고받을 수 있다 (import되거나 export된 global, table set 또는 get 연산, 그리고 함수 인수 또는 반환값을 통해) externref 값으로서.

다중 테이블

여러 테이블은 JavaScript로부터 그리고 JavaScript로 export 및 import될 수 있다.

10.2. 릴리스 3.0

다중 메모리

여러 메모리는 JavaScript로부터 그리고 JavaScript로 export 및 import될 수 있다.

JS 문자열 빌트인

모듈을 컴파일할 때 builtins 옵션이 추가되었고, JS 문자열을 조작하기 위한 빌트인 함수 모음이 추가되었다.

적합성

문서 규약

적합성 요구 사항은 서술적 단언 과 RFC 2119 용어의 조합으로 표현된다. 이 문서의 규범적 부분에서 사용되는 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 및 “OPTIONAL”은 RFC 2119에 설명된 대로 해석되어야 한다. 그러나 가독성을 위해, 이 명세에서는 이 단어들이 모두 대문자로 나타나지 않는다.

이 명세의 모든 텍스트는 규범적이며 명시적으로 비규범적으로 표시된 절, 예시, 그리고 주석만 예외이다. [RFC2119]

이 명세의 예시는 “for example” 이라는 단어로 도입되거나 규범적 텍스트와 구분되며 class="example"로 표시된다, 다음과 같이:

이것은 정보 제공용 예시의 예이다.

정보 제공용 주석은 “Note” 라는 단어로 시작하고 규범적 텍스트와 구분되며 class="note"로 표시된다, 다음과 같이:

참고, 이것은 정보 제공용 주석이다.

적합한 알고리즘

알고리즘의 일부로 명령형으로 표현된 요구 사항은 (예: "선행 공백 문자를 모두 제거한다" 또는 "false를 반환하고 이 단계를 중단한다") 그 알고리즘을 도입할 때 사용된 핵심 단어의 의미로 해석되어야 한다 ("must", "should", "may" 등).

알고리즘이나 특정 단계로 표현된 적합성 요구 사항은 최종 결과가 동등하기만 하다면, 어떤 방식으로든 구현될 수 있다. 특히, 이 명세에서 정의된 알고리즘은 이해하기 쉽게 하려는 목적이며 성능을 목표로 하지 않는다. 구현자는 최적화를 권장받는다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[ECMASCRIPT]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. 인코딩 표준. Living Standard. URL: https://encoding.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML 표준. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. 요구 수준을 나타내기 위해 RFC에서 사용하는 핵심 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBASSEMBLY]
WebAssembly 코어 명세. Draft. URL: https://webassembly.github.io/spec/core/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. Living Standard. URL: https://webidl.spec.whatwg.org/

정보 제공용 참고 문헌

[IEEE-754]
부동소수점 산술을 위한 IEEE 표준 . 2019년 7월 22일. URL: https://ieeexplore.ieee.org/document/8766229
[WASMWEB]
WebAssembly 웹 API 명세. Draft. URL: https://webassembly.github.io/spec/web-api/

IDL 색인

dictionary WebAssemblyInstantiatedSource {
    required Module module;
    required Instance instance;
};

dictionary WebAssemblyCompileOptions {
    USVString? importedStringConstants = null;
    sequence<USVString> builtins = [];
};

[Exposed=*]
namespace WebAssembly {
    boolean validate([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});
    Promise<Module> compile([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});

    Promise<WebAssemblyInstantiatedSource> instantiate(
        [AllowResizable] AllowSharedBufferSource bytes, optional object importObject, optional WebAssemblyCompileOptions options = {});

    Promise<Instance> instantiate(
        Module moduleObject, optional object importObject);

    readonly attribute Tag JSTag;
};

enum ImportExportKind {
  "function",
  "table",
  "memory",
  "global",
  "tag"
};

enum AddressType {
  "i32",
  "i64",
};

typedef any AddressValue;

dictionary ModuleExportDescriptor {
  required USVString name;
  required ImportExportKind kind;
  // Note: Other fields such as signature may be added in the future.
};

dictionary ModuleImportDescriptor {
  required USVString module;
  required USVString name;
  required ImportExportKind kind;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Module {
  constructor([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {});
  static sequence<ModuleExportDescriptor> exports(Module moduleObject);
  static sequence<ModuleImportDescriptor> imports(Module moduleObject);
  static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName);
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Instance {
  constructor(Module module, optional object importObject);
  readonly attribute object exports;
};

dictionary MemoryDescriptor {
  required AddressValue initial;
  AddressValue maximum;
  AddressType address;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Memory {
  constructor(MemoryDescriptor descriptor);
  AddressValue grow(AddressValue delta);
  ArrayBuffer toFixedLengthBuffer();
  ArrayBuffer toResizableBuffer();
  readonly attribute ArrayBuffer buffer;
};

enum TableKind {
  "externref",
  "anyfunc",
  // Note: More values may be added in future iterations,
  // e.g., typed function references, typed GC references
};

dictionary TableDescriptor {
  required TableKind element;
  required AddressValue initial;
  AddressValue maximum;
  AddressType address;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Table {
  constructor(TableDescriptor descriptor, optional any value);
  AddressValue grow(AddressValue delta, optional any value);
  any get(AddressValue index);
  undefined set(AddressValue index, optional any value);
  readonly attribute AddressValue length;
};

enum ValueType {
  "i32",
  "i64",
  "f32",
  "f64",
  "v128",
  "externref",
  "anyfunc",
};

dictionary GlobalDescriptor {
  required ValueType value;
  boolean mutable = false;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Global {
  constructor(GlobalDescriptor descriptor, optional any v);
  any valueOf();
  attribute any value;
};

dictionary TagType {
  required sequence<ValueType> parameters;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Tag {
  constructor(TagType type);
};

dictionary ExceptionOptions {
  boolean traceStack = false;
};

[LegacyNamespace=WebAssembly, Exposed=*]
interface Exception {
  constructor(Tag exceptionTag, sequence<any> payload, optional ExceptionOptions options = {});
  any getArg(Tag exceptionTag, [EnforceRange] unsigned long index);
  boolean is(Tag exceptionTag);
  readonly attribute (DOMString or undefined) stack;
};

이슈 색인

큰 테이블 또는 메모리의 할당 실패는 다음 중 하나를 초래할 수 있다 향후 개정에서는 대량의 메모리 할당에 대해 보다 신뢰 가능하고 복구 가능한 오류를 다시 고려할 수 있다.

추가 논의는 Issue 879를 참조하라.

↵